Skip to content

Commit 53bc1f3

Browse files
committed
chore: resolve conflicts from V8
2 parents 1a2bdd1 + cf0dbec commit 53bc1f3

File tree

96 files changed

+3213
-1383
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+3213
-1383
lines changed

examples/SampleApp/App.tsx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { createStackNavigator } from '@react-navigation/stack';
66
import { SafeAreaProvider } from 'react-native-safe-area-context';
77
import {
88
Chat,
9+
createTextComposerEmojiMiddleware,
910
OverlayProvider,
1011
SqliteClient,
1112
ThemeProvider,
@@ -34,8 +35,12 @@ import { OneOnOneChannelDetailScreen } from './src/screens/OneOnOneChannelDetail
3435
import { SharedGroupsScreen } from './src/screens/SharedGroupsScreen';
3536
import { ThreadScreen } from './src/screens/ThreadScreen';
3637
import { UserSelectorScreen } from './src/screens/UserSelectorScreen';
38+
import { init, SearchIndex } from 'emoji-mart';
39+
import data from '@emoji-mart/data';
3740

38-
import type { LocalMessage, StreamChat } from 'stream-chat';
41+
import type { LocalMessage, StreamChat, TextComposerMiddleware } from 'stream-chat';
42+
43+
init({ data });
3944

4045
if (__DEV__) {
4146
DevSettings.addMenuItem('Reset local DB (offline storage)', () => {
@@ -118,6 +123,25 @@ const App = () => {
118123
};
119124
}, []);
120125

126+
useEffect(() => {
127+
if (!chatClient) {
128+
return;
129+
}
130+
chatClient.setMessageComposerSetupFunction(({ composer }) => {
131+
composer.updateConfig({
132+
drafts: {
133+
enabled: true,
134+
},
135+
});
136+
137+
composer.textComposer.middlewareExecutor.insert({
138+
middleware: [createTextComposerEmojiMiddleware(SearchIndex) as TextComposerMiddleware],
139+
position: { after: 'stream-io/text-composer/mentions-middleware' },
140+
unique: true,
141+
});
142+
});
143+
}, [chatClient]);
144+
121145
return (
122146
<SafeAreaProvider
123147
style={{

examples/SampleApp/ios/Podfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2667,4 +2667,4 @@ SPEC CHECKSUMS:
26672667

26682668
PODFILE CHECKSUM: 4f662370295f8f9cee909f1a4c59a614999a209d
26692669

2670-
COCOAPODS: 1.16.2
2670+
COCOAPODS: 1.14.3

examples/SampleApp/src/components/BottomTabs.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { MentionsTab } from '../icons/MentionsTab';
1111

1212
import type { BottomTabBarProps } from '@react-navigation/bottom-tabs';
1313
import type { Route } from '@react-navigation/native';
14+
import { DraftsTab } from '../icons/DraftsTab';
1415

1516
const styles = StyleSheet.create({
1617
notification: {
@@ -44,6 +45,13 @@ const getTab = (key: string) => {
4445
notification: <ChannelsUnreadCountBadge />,
4546
title: 'Chats',
4647
};
48+
case 'DraftsScreen':
49+
return {
50+
icon: <DraftsTab />,
51+
iconActive: <DraftsTab active />,
52+
title: 'Drafts',
53+
notification: <ChannelsUnreadCountBadge />,
54+
};
4755
case 'ThreadsScreen':
4856
return {
4957
icon: <ThreadsTab />,

examples/SampleApp/src/components/ChannelPreview.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,7 @@ const CustomChannelPreviewStatus = (
7171
);
7272
};
7373

74-
export const ChannelPreview: React.FC<ChannelPreviewMessengerProps> = (
75-
props,
76-
) => {
74+
export const ChannelPreview: React.FC<ChannelPreviewMessengerProps> = (props) => {
7775
const { channel } = props;
7876

7977
const { setOverlay } = useAppOverlayContext();
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
import { FlatList, Pressable, StyleSheet, Text, View } from 'react-native';
2+
import { DraftsIcon } from '../icons/DraftIcon';
3+
import {
4+
FileTypes,
5+
MessagePreview,
6+
TranslationContextValue,
7+
useChatContext,
8+
useStateStore,
9+
useTheme,
10+
useTranslationContext,
11+
} from 'stream-chat-react-native';
12+
import { DraftManagerState, DraftsManager } from '../utils/DraftsManager';
13+
import { useCallback, useEffect, useMemo } from 'react';
14+
import dayjs from 'dayjs';
15+
import { useIsFocused, useNavigation } from '@react-navigation/native';
16+
import { ChannelResponse, DraftMessage, DraftResponse, MessageResponseBase } from 'stream-chat';
17+
18+
export type DraftItemProps = {
19+
type?: 'channel' | 'thread';
20+
channel?: ChannelResponse;
21+
date?: string;
22+
message: DraftMessage;
23+
// TODO: Fix the type for thread
24+
thread?: MessageResponseBase;
25+
};
26+
27+
export const attachmentTypeIconMap = {
28+
audio: '🔈',
29+
file: '📄',
30+
image: '📷',
31+
video: '🎥',
32+
voiceRecording: '🎙️',
33+
} as const;
34+
35+
const getPreviewFromMessage = ({
36+
t,
37+
draftMessage,
38+
}: {
39+
t: TranslationContextValue['t'];
40+
draftMessage: DraftMessage;
41+
}) => {
42+
if (draftMessage.attachments?.length) {
43+
const attachment = draftMessage?.attachments?.at(0);
44+
45+
const attachmentIcon = attachment
46+
? `${
47+
attachmentTypeIconMap[
48+
(attachment.type as keyof typeof attachmentTypeIconMap) ?? 'file'
49+
] ?? attachmentTypeIconMap.file
50+
} `
51+
: '';
52+
53+
if (attachment?.type === FileTypes.VoiceRecording) {
54+
return [
55+
{ bold: false, text: attachmentIcon },
56+
{
57+
bold: false,
58+
text: t('Voice message'),
59+
},
60+
];
61+
}
62+
return [
63+
{ bold: false, text: attachmentIcon },
64+
{
65+
bold: false,
66+
text:
67+
attachment?.type === FileTypes.Image
68+
? attachment?.fallback
69+
? attachment?.fallback
70+
: 'N/A'
71+
: attachment?.title
72+
? attachment?.title
73+
: 'N/A',
74+
},
75+
];
76+
}
77+
78+
if (draftMessage.text) {
79+
return [
80+
{
81+
bold: false,
82+
text: draftMessage.text,
83+
},
84+
];
85+
}
86+
};
87+
88+
export const DraftItem = ({ type, channel, date, message, thread }: DraftItemProps) => {
89+
const {
90+
theme: {
91+
colors: { grey },
92+
},
93+
} = useTheme();
94+
const navigation = useNavigation();
95+
const { client } = useChatContext();
96+
const { t } = useTranslationContext();
97+
const channelName = channel?.name ? channel.name : 'Channel';
98+
99+
const onNavigationHandler = async () => {
100+
if (channel?.type && channel.id) {
101+
const resultChannel = client.channel(channel?.type, channel?.id);
102+
await resultChannel?.watch();
103+
104+
if (type === 'thread' && thread?.id) {
105+
navigation.navigate('ThreadScreen', {
106+
thread,
107+
channel: resultChannel,
108+
});
109+
} else if (type === 'channel') {
110+
navigation.navigate('ChannelScreen', { channel: resultChannel });
111+
}
112+
}
113+
};
114+
115+
const previews = useMemo(() => {
116+
return getPreviewFromMessage({ draftMessage: message, t });
117+
}, [message, t]);
118+
119+
return (
120+
<Pressable
121+
style={({ pressed }) => [styles.itemContainer, { opacity: pressed ? 0.8 : 1 }]}
122+
onPress={onNavigationHandler}
123+
>
124+
<View style={styles.header}>
125+
<Text style={styles.name}>
126+
{type === 'channel' ? `# ${channelName}` : `Thread in # ${channelName}`}
127+
</Text>
128+
<Text style={[styles.date, { color: grey }]}>{dayjs(date).fromNow()}</Text>
129+
</View>
130+
<View style={styles.content}>
131+
<View style={styles.icon}>
132+
<DraftsIcon />
133+
</View>
134+
<MessagePreview previews={previews} />
135+
</View>
136+
</Pressable>
137+
);
138+
};
139+
140+
const selector = (nextValue: DraftManagerState) =>
141+
({
142+
isLoading: nextValue.pagination.isLoading,
143+
isLoadingNext: nextValue.pagination.isLoadingNext,
144+
drafts: nextValue.drafts,
145+
}) as const;
146+
147+
const renderItem = ({ item }: { item: DraftResponse }) => (
148+
<DraftItem
149+
channel={item.channel}
150+
type={item.parent_id ? 'thread' : 'channel'}
151+
date={item.created_at}
152+
message={item.message}
153+
thread={item.parent_message}
154+
/>
155+
);
156+
157+
const renderEmptyComponent = () => (
158+
<Text style={{ textAlign: 'center', padding: 20 }}>No drafts available</Text>
159+
);
160+
161+
export const DraftsList = () => {
162+
const isFocused = useIsFocused();
163+
const { client } = useChatContext();
164+
const draftsManager = useMemo(() => new DraftsManager({ client }), [client]);
165+
166+
useEffect(() => {
167+
if (isFocused) {
168+
draftsManager.activate();
169+
} else {
170+
draftsManager.deactivate();
171+
}
172+
}, [draftsManager, isFocused]);
173+
174+
useEffect(() => {
175+
draftsManager.registerSubscriptions();
176+
177+
return () => {
178+
draftsManager.deactivate();
179+
draftsManager.unregisterSubscriptions();
180+
};
181+
}, [draftsManager]);
182+
183+
const { isLoading, drafts } = useStateStore(draftsManager.state, selector);
184+
185+
const onRefresh = useCallback(() => {
186+
draftsManager.reload({ force: true });
187+
}, [draftsManager]);
188+
189+
const onEndReached = useCallback(() => {
190+
draftsManager.loadNextPage();
191+
}, [draftsManager]);
192+
193+
return (
194+
<FlatList
195+
contentContainerStyle={{ flexGrow: 1 }}
196+
data={drafts}
197+
refreshing={isLoading}
198+
keyExtractor={(item) => item.message.id}
199+
renderItem={renderItem}
200+
onRefresh={onRefresh}
201+
ListEmptyComponent={renderEmptyComponent}
202+
onEndReached={onEndReached}
203+
/>
204+
);
205+
};
206+
207+
const styles = StyleSheet.create({
208+
itemContainer: {
209+
paddingVertical: 8,
210+
marginHorizontal: 8,
211+
borderBottomWidth: 1,
212+
borderBottomColor: '#ccc',
213+
},
214+
header: {
215+
flexDirection: 'row',
216+
alignItems: 'center',
217+
justifyContent: 'space-between',
218+
},
219+
name: {
220+
fontSize: 16,
221+
fontWeight: 'bold',
222+
},
223+
date: {},
224+
content: {
225+
flexDirection: 'row',
226+
alignItems: 'center',
227+
marginTop: 4,
228+
},
229+
icon: {},
230+
text: {
231+
marginLeft: 8,
232+
flexShrink: 1,
233+
},
234+
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from 'react';
2+
import Svg, { Path } from 'react-native-svg';
3+
import { useTheme } from 'stream-chat-react-native';
4+
5+
import { IconProps } from '../utils/base';
6+
7+
export const DraftsIcon: React.FC<IconProps> = ({ height = 29, width = 30 }) => {
8+
const {
9+
theme: {
10+
colors: { grey },
11+
},
12+
} = useTheme();
13+
return (
14+
<Svg fill='none' height={height} viewBox={`0 0 ${height} ${width}`} width={width}>
15+
<Path
16+
clipRule='evenodd'
17+
d='M7.93652 28.729C7.53808 28.729 7.22754 28.6001 7.00488 28.3423C6.78222 28.0845 6.67089 27.7329 6.67089 27.2876V24.4048H5.98535C4.93066 24.4048 4.02539 24.2026 3.26953 23.7983C2.51367 23.3999 1.93359 22.8198 1.52929 22.0581C1.125 21.2905 0.922848 20.3706 0.922848 19.2983V10.3071C0.922848 9.23486 1.12207 8.31787 1.5205 7.55615C1.9248 6.78857 2.50781 6.20264 3.26953 5.79834C4.03125 5.39404 4.95703 5.19189 6.04687 5.19189H20.6103L18.668 7.12549H6.09961C5.3789 7.12549 4.77832 7.25146 4.29785 7.50342C3.82324 7.74951 3.46582 8.11279 3.22558 8.59326C2.98535 9.07373 2.86523 9.6626 2.86523 10.3599V19.228C2.86523 19.9312 2.98535 20.5229 3.22558 21.0034C3.46582 21.4839 3.82324 21.8501 4.29785 22.1021C4.77832 22.3481 5.3789 22.4712 6.09961 22.4712H7.59375C7.88086 22.4712 8.08886 22.5327 8.21777 22.6558C8.35254 22.7788 8.41992 22.9897 8.41992 23.2886V26.5493L12.0674 23.0161C12.29 22.7935 12.4951 22.647 12.6826 22.5767C12.8701 22.5063 13.1221 22.4712 13.4385 22.4712H20.8916C21.6064 22.4712 22.2012 22.3481 22.6758 22.1021C23.1562 21.8501 23.5166 21.4839 23.7568 21.0034C24.0029 20.5229 24.126 19.9312 24.126 19.228V9.99072L26.0684 8.04834V19.2983C26.0684 20.3647 25.8662 21.2817 25.4619 22.0493C25.0635 22.811 24.4834 23.394 23.7217 23.7983C22.9658 24.2026 22.04 24.4048 20.9443 24.4048H13.5088L9.58007 27.8589C9.25195 28.1519 8.96484 28.3687 8.71875 28.5093C8.47851 28.6558 8.21777 28.729 7.93652 28.729ZM15.1611 15.1587C15.0439 15.2056 14.9326 15.1792 14.8271 15.0796C14.7275 14.98 14.707 14.8687 14.7656 14.7456L15.8379 12.4956L25.541 2.79248L27.1758 4.41846L17.4639 14.1216L15.1611 15.1587ZM28.0107 3.5835L26.3848 1.93994L27.1846 1.15771C27.3896 0.946777 27.6269 0.83252 27.8965 0.814941C28.166 0.797363 28.3916 0.882324 28.5732 1.06982L28.8457 1.32471C29.0566 1.53564 29.1592 1.77588 29.1533 2.04541C29.1475 2.30908 29.0332 2.55225 28.8105 2.7749L28.0107 3.5835Z'
18+
fill={grey}
19+
fillRule='evenodd'
20+
/>
21+
</Svg>
22+
);
23+
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from 'react';
2+
import Svg, { Path } from 'react-native-svg';
3+
import { useTheme } from 'stream-chat-react-native';
4+
5+
import { IconProps } from '../utils/base';
6+
7+
export const DraftsTab: React.FC<IconProps> = ({ active, height = 29, width = 30 }) => {
8+
const {
9+
theme: {
10+
colors: { black, grey },
11+
},
12+
} = useTheme();
13+
return (
14+
<Svg fill='none' height={height} viewBox={`0 0 ${height} ${width}`} width={width}>
15+
<Path
16+
clipRule='evenodd'
17+
d='M7.93652 28.729C7.53808 28.729 7.22754 28.6001 7.00488 28.3423C6.78222 28.0845 6.67089 27.7329 6.67089 27.2876V24.4048H5.98535C4.93066 24.4048 4.02539 24.2026 3.26953 23.7983C2.51367 23.3999 1.93359 22.8198 1.52929 22.0581C1.125 21.2905 0.922848 20.3706 0.922848 19.2983V10.3071C0.922848 9.23486 1.12207 8.31787 1.5205 7.55615C1.9248 6.78857 2.50781 6.20264 3.26953 5.79834C4.03125 5.39404 4.95703 5.19189 6.04687 5.19189H20.6103L18.668 7.12549H6.09961C5.3789 7.12549 4.77832 7.25146 4.29785 7.50342C3.82324 7.74951 3.46582 8.11279 3.22558 8.59326C2.98535 9.07373 2.86523 9.6626 2.86523 10.3599V19.228C2.86523 19.9312 2.98535 20.5229 3.22558 21.0034C3.46582 21.4839 3.82324 21.8501 4.29785 22.1021C4.77832 22.3481 5.3789 22.4712 6.09961 22.4712H7.59375C7.88086 22.4712 8.08886 22.5327 8.21777 22.6558C8.35254 22.7788 8.41992 22.9897 8.41992 23.2886V26.5493L12.0674 23.0161C12.29 22.7935 12.4951 22.647 12.6826 22.5767C12.8701 22.5063 13.1221 22.4712 13.4385 22.4712H20.8916C21.6064 22.4712 22.2012 22.3481 22.6758 22.1021C23.1562 21.8501 23.5166 21.4839 23.7568 21.0034C24.0029 20.5229 24.126 19.9312 24.126 19.228V9.99072L26.0684 8.04834V19.2983C26.0684 20.3647 25.8662 21.2817 25.4619 22.0493C25.0635 22.811 24.4834 23.394 23.7217 23.7983C22.9658 24.2026 22.04 24.4048 20.9443 24.4048H13.5088L9.58007 27.8589C9.25195 28.1519 8.96484 28.3687 8.71875 28.5093C8.47851 28.6558 8.21777 28.729 7.93652 28.729ZM15.1611 15.1587C15.0439 15.2056 14.9326 15.1792 14.8271 15.0796C14.7275 14.98 14.707 14.8687 14.7656 14.7456L15.8379 12.4956L25.541 2.79248L27.1758 4.41846L17.4639 14.1216L15.1611 15.1587ZM28.0107 3.5835L26.3848 1.93994L27.1846 1.15771C27.3896 0.946777 27.6269 0.83252 27.8965 0.814941C28.166 0.797363 28.3916 0.882324 28.5732 1.06982L28.8457 1.32471C29.0566 1.53564 29.1592 1.77588 29.1533 2.04541C29.1475 2.30908 29.0332 2.55225 28.8105 2.7749L28.0107 3.5835Z'
18+
fill={active ? black : grey}
19+
fillRule='evenodd'
20+
/>
21+
</Svg>
22+
);
23+
};

0 commit comments

Comments
 (0)