Skip to content

Commit e8b680f

Browse files
committed
fix: optimize sample app code
1 parent 5c3a35d commit e8b680f

File tree

9 files changed

+124
-159
lines changed

9 files changed

+124
-159
lines changed

examples/SampleApp/src/components/DraftsList.tsx

Lines changed: 2 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import { FlatList, Pressable, StyleSheet, Text, View } from 'react-native';
22
import { DraftsIcon } from '../icons/DraftIcon';
33
import {
4-
FileTypes,
54
MessagePreview,
6-
TranslationContextValue,
75
useChatContext,
86
useStateStore,
97
useTheme,
@@ -14,6 +12,7 @@ import { useCallback, useEffect, useMemo } from 'react';
1412
import dayjs from 'dayjs';
1513
import { useIsFocused, useNavigation } from '@react-navigation/native';
1614
import { ChannelResponse, DraftMessage, DraftResponse, MessageResponseBase } from 'stream-chat';
15+
import { getPreviewFromMessage } from '../utils/getPreviewOfMessage';
1716

1817
export type DraftItemProps = {
1918
type?: 'channel' | 'thread';
@@ -24,67 +23,6 @@ export type DraftItemProps = {
2423
thread?: MessageResponseBase;
2524
};
2625

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-
8826
export const DraftItem = ({ type, channel, date, message, thread }: DraftItemProps) => {
8927
const {
9028
theme: {
@@ -113,7 +51,7 @@ export const DraftItem = ({ type, channel, date, message, thread }: DraftItemPro
11351
};
11452

11553
const previews = useMemo(() => {
116-
return getPreviewFromMessage({ draftMessage: message, t });
54+
return getPreviewFromMessage({ message, t });
11755
}, [message, t]);
11856

11957
return (

examples/SampleApp/src/components/Reminders/MessageReminderHeader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import {
22
MessageFooterProps,
33
Time,
4+
useMessageReminder,
45
useStateStore,
56
useTranslationContext,
67
} from 'stream-chat-react-native';
7-
import { useMessageReminder } from '../../hooks/useMessageReminder';
88
import { ReminderState } from 'stream-chat';
99
import { StyleSheet, Text, View } from 'react-native';
1010

examples/SampleApp/src/components/Reminders/ReminderBanner.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { StyleSheet, Text, View } from 'react-native';
22
import { ReminderResponse, ReminderState } from 'stream-chat';
3-
import { useTheme, useTranslationContext, useStateStore } from 'stream-chat-react-native';
4-
import { useMessageReminder } from '../../hooks/useMessageReminder';
3+
import {
4+
useMessageReminder,
5+
useTheme,
6+
useTranslationContext,
7+
useStateStore,
8+
} from 'stream-chat-react-native';
59

610
const reminderStateSelector = (state: ReminderState) => ({
711
timeLeftMs: state.timeLeftMs,

examples/SampleApp/src/components/Reminders/ReminderItem.tsx

Lines changed: 2 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,17 @@
11
import { useNavigation } from '@react-navigation/native';
22
import { useCallback, useMemo } from 'react';
33
import { Alert, AlertButton, Pressable, StyleSheet, Text, View } from 'react-native';
4-
import { MessageResponse, ReminderResponse } from 'stream-chat';
4+
import { ReminderResponse } from 'stream-chat';
55
import {
66
Delete,
7-
FileTypes,
87
MessagePreview,
9-
TranslationContextValue,
108
useChatContext,
119
useTheme,
1210
useTranslationContext,
1311
} from 'stream-chat-react-native';
1412
import { ReminderBanner } from './ReminderBanner';
1513
import Swipeable from 'react-native-gesture-handler/ReanimatedSwipeable';
16-
17-
export const attachmentTypeIconMap = {
18-
audio: '🔈',
19-
file: '📄',
20-
image: '📷',
21-
video: '🎥',
22-
voiceRecording: '🎙️',
23-
} as const;
24-
25-
const getPreviewFromMessage = ({
26-
t,
27-
message,
28-
}: {
29-
t: TranslationContextValue['t'];
30-
message: MessageResponse;
31-
}) => {
32-
if (message.attachments?.length) {
33-
const attachment = message?.attachments?.at(0);
34-
35-
const attachmentIcon = attachment
36-
? `${
37-
attachmentTypeIconMap[
38-
(attachment.type as keyof typeof attachmentTypeIconMap) ?? 'file'
39-
] ?? attachmentTypeIconMap.file
40-
} `
41-
: '';
42-
43-
if (attachment?.type === FileTypes.VoiceRecording) {
44-
return [
45-
{ bold: false, text: attachmentIcon },
46-
{
47-
bold: false,
48-
text: t('Voice message'),
49-
},
50-
];
51-
}
52-
return [
53-
{ bold: false, text: attachmentIcon },
54-
{
55-
bold: false,
56-
text:
57-
attachment?.type === FileTypes.Image
58-
? attachment?.fallback
59-
? attachment?.fallback
60-
: 'N/A'
61-
: attachment?.title
62-
? attachment?.title
63-
: 'N/A',
64-
},
65-
];
66-
}
67-
68-
if (message.poll_id) {
69-
return [
70-
{
71-
bold: false,
72-
text: '📊',
73-
},
74-
{
75-
bold: false,
76-
text: 'Poll',
77-
},
78-
];
79-
}
80-
81-
return [
82-
{
83-
bold: false,
84-
text: message.text ?? '',
85-
},
86-
];
87-
};
14+
import { getPreviewFromMessage } from '../../utils/getPreviewOfMessage';
8815

8916
export const ReminderItem = (
9017
item: ReminderResponse & { onDeleteHandler?: (id: string) => void },

examples/SampleApp/src/screens/ChannelScreen.tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
useTypingString,
1515
AITypingIndicatorView,
1616
useTranslationContext,
17+
MessageActionsParams,
1718
} from 'stream-chat-react-native';
1819
import { Platform, Pressable, StyleSheet, View } from 'react-native';
1920
import type { StackNavigationProp } from '@react-navigation/stack';
@@ -161,6 +162,21 @@ export const ChannelScreen: React.FC<ChannelScreenProps> = ({
161162
[channel, navigation],
162163
);
163164

165+
const messageActions = useCallback(
166+
(params: MessageActionsParams) => {
167+
if (!chatClient) {
168+
return [];
169+
}
170+
return channelMessageActions({
171+
params,
172+
chatClient,
173+
t,
174+
colors,
175+
});
176+
},
177+
[chatClient, colors, t],
178+
);
179+
164180
if (!channel || !chatClient) {
165181
return null;
166182
}
@@ -174,14 +190,7 @@ export const ChannelScreen: React.FC<ChannelScreenProps> = ({
174190
enforceUniqueReaction
175191
initialScrollToFirstUnreadMessage
176192
keyboardVerticalOffset={Platform.OS === 'ios' ? 0 : -300}
177-
messageActions={(params) => {
178-
return channelMessageActions({
179-
params,
180-
chatClient,
181-
t,
182-
colors,
183-
});
184-
}}
193+
messageActions={messageActions}
185194
MessageHeader={MessageReminderHeader}
186195
messageId={messageId}
187196
NetworkDownIndicator={() => null}

examples/SampleApp/src/screens/ThreadScreen.tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import React from 'react';
1+
import React, { useCallback } from 'react';
22
import { Platform, StyleSheet, View } from 'react-native';
33
import { SafeAreaView } from 'react-native-safe-area-context';
44
import {
55
Channel,
6+
MessageActionsParams,
67
Thread,
78
ThreadType,
89
useChatContext,
@@ -74,20 +75,28 @@ export const ThreadScreen: React.FC<ThreadScreenProps> = ({
7475
const { client: chatClient } = useChatContext();
7576
const { t } = useTranslationContext();
7677

78+
const messageActions = useCallback(
79+
(params: MessageActionsParams) => {
80+
if (!chatClient) {
81+
return [];
82+
}
83+
return channelMessageActions({
84+
params,
85+
chatClient,
86+
t,
87+
});
88+
},
89+
[chatClient, t],
90+
);
91+
7792
return (
7893
<SafeAreaView style={[styles.container, { backgroundColor: white }]}>
7994
<Channel
8095
audioRecordingEnabled={true}
8196
channel={channel}
8297
enforceUniqueReaction
8398
keyboardVerticalOffset={Platform.OS === 'ios' ? 0 : -300}
84-
messageActions={(params) => {
85-
return channelMessageActions({
86-
params,
87-
chatClient,
88-
t,
89-
});
90-
}}
99+
messageActions={messageActions}
91100
MessageHeader={MessageReminderHeader}
92101
thread={thread}
93102
threadList
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { DraftMessage, LocalMessage, MessageResponse } from 'stream-chat';
2+
import { FileTypes, TranslationContextValue } from 'stream-chat-react-native';
3+
4+
export const attachmentTypeIconMap = {
5+
audio: '🔈',
6+
file: '📄',
7+
image: '📷',
8+
video: '🎥',
9+
voiceRecording: '🎙️',
10+
} as const;
11+
12+
export const getPreviewFromMessage = ({
13+
t,
14+
message,
15+
}: {
16+
t: TranslationContextValue['t'];
17+
message: MessageResponse | LocalMessage | DraftMessage;
18+
}) => {
19+
if (message.attachments?.length) {
20+
const attachment = message?.attachments?.at(0);
21+
22+
const attachmentIcon = attachment
23+
? `${
24+
attachmentTypeIconMap[
25+
(attachment.type as keyof typeof attachmentTypeIconMap) ?? 'file'
26+
] ?? attachmentTypeIconMap.file
27+
} `
28+
: '';
29+
30+
if (attachment?.type === FileTypes.VoiceRecording) {
31+
return [
32+
{ bold: false, text: attachmentIcon },
33+
{
34+
bold: false,
35+
text: t('Voice message'),
36+
},
37+
];
38+
}
39+
return [
40+
{ bold: false, text: attachmentIcon },
41+
{
42+
bold: false,
43+
text:
44+
attachment?.type === FileTypes.Image
45+
? attachment?.fallback
46+
? attachment?.fallback
47+
: 'N/A'
48+
: attachment?.title
49+
? attachment?.title
50+
: 'N/A',
51+
},
52+
];
53+
}
54+
55+
if (message.poll_id) {
56+
return [
57+
{
58+
bold: false,
59+
text: '📊',
60+
},
61+
{
62+
bold: false,
63+
text: 'Poll',
64+
},
65+
];
66+
}
67+
68+
return [
69+
{
70+
bold: false,
71+
text: message.text ?? '',
72+
},
73+
];
74+
};

package/src/hooks/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export * from './useScreenDimensions';
55
export * from './useStateStore';
66
export * from './useStableCallback';
77
export * from './useLoadingImage';
8+
export * from './useMessageReminder';

examples/SampleApp/src/hooks/useMessageReminder.ts renamed to package/src/hooks/useMessageReminder.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { useCallback } from 'react';
22

33
import type { ReminderManagerState } from 'stream-chat';
4-
import { useChatContext, useStateStore } from 'stream-chat-react-native';
4+
5+
import { useStateStore } from './useStateStore';
6+
7+
import { useChatContext } from '../contexts/chatContext/ChatContext';
58

69
export const useMessageReminder = (messageId: string) => {
710
const { client } = useChatContext();

0 commit comments

Comments
 (0)