@messenger-box/platform-mobile 10.0.3-alpha.14 → 10.0.3-alpha.143
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +216 -0
- package/lib/compute.js +2 -3
- package/lib/compute.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/module.js.map +1 -1
- package/lib/queries/inboxQueries.js +65 -0
- package/lib/queries/inboxQueries.js.map +1 -0
- package/lib/routes.json +2 -3
- package/lib/screens/inbox/DialogMessages.js +5 -3
- package/lib/screens/inbox/DialogMessages.js.map +1 -1
- package/lib/screens/inbox/DialogThreadMessages.js +3 -7
- package/lib/screens/inbox/DialogThreadMessages.js.map +1 -1
- package/lib/screens/inbox/DialogThreads.js +57 -18
- package/lib/screens/inbox/DialogThreads.js.map +1 -1
- package/lib/screens/inbox/Inbox.js.map +1 -1
- package/lib/screens/inbox/components/CachedImage/consts.js +1 -1
- package/lib/screens/inbox/components/CachedImage/consts.js.map +1 -1
- package/lib/screens/inbox/components/CachedImage/index.js +168 -46
- package/lib/screens/inbox/components/CachedImage/index.js.map +1 -1
- package/lib/screens/inbox/components/DialogItem.js +169 -0
- package/lib/screens/inbox/components/DialogItem.js.map +1 -0
- package/lib/screens/inbox/components/GiftedChatInboxComponent.js +313 -0
- package/lib/screens/inbox/components/GiftedChatInboxComponent.js.map +1 -0
- package/lib/screens/inbox/components/SlackMessageContainer/ImageViewerModal.js.map +1 -1
- package/lib/screens/inbox/components/SlackMessageContainer/PaymentMessage.js +197 -0
- package/lib/screens/inbox/components/SlackMessageContainer/PaymentMessage.js.map +1 -0
- package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js +141 -31
- package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js.map +1 -1
- package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js.map +1 -1
- package/lib/screens/inbox/components/SubscriptionHandler.js +24 -0
- package/lib/screens/inbox/components/SubscriptionHandler.js.map +1 -0
- package/lib/screens/inbox/components/ThreadsViewItem.js +66 -44
- package/lib/screens/inbox/components/ThreadsViewItem.js.map +1 -1
- package/lib/screens/inbox/config/config.js +2 -2
- package/lib/screens/inbox/config/config.js.map +1 -1
- package/lib/screens/inbox/containers/ConversationView.js +1205 -432
- package/lib/screens/inbox/containers/ConversationView.js.map +1 -1
- package/lib/screens/inbox/containers/Dialogs.js +193 -80
- package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
- package/lib/screens/inbox/containers/ThreadConversationView.js +724 -207
- package/lib/screens/inbox/containers/ThreadConversationView.js.map +1 -1
- package/lib/screens/inbox/containers/ThreadsView.js +83 -50
- package/lib/screens/inbox/containers/ThreadsView.js.map +1 -1
- package/lib/screens/inbox/hooks/useInboxMessages.js +31 -0
- package/lib/screens/inbox/hooks/useInboxMessages.js.map +1 -0
- package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js +108 -0
- package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js.map +1 -0
- package/lib/screens/inbox/workflow/dialog-threads-xstate.js +151 -0
- package/lib/screens/inbox/workflow/dialog-threads-xstate.js.map +1 -0
- package/package.json +4 -4
- package/src/index.ts +2 -0
- package/src/queries/inboxQueries.ts +299 -0
- package/src/queries/index.d.ts +2 -0
- package/src/queries/index.ts +1 -0
- package/src/screens/inbox/DialogMessages.tsx +2 -1
- package/src/screens/inbox/DialogThreadMessages.tsx +3 -11
- package/src/screens/inbox/DialogThreads.tsx +53 -60
- package/src/screens/inbox/components/Actionsheet.tsx +30 -0
- package/src/screens/inbox/components/CachedImage/consts.ts +4 -3
- package/src/screens/inbox/components/CachedImage/index.tsx +232 -61
- package/src/screens/inbox/components/DialogItem.tsx +306 -0
- package/src/screens/inbox/components/DialogsListItem.tsx +257 -176
- package/src/screens/inbox/components/ExpandableInput.tsx +460 -0
- package/src/screens/inbox/components/ExpandableInputActionSheet.tsx +518 -0
- package/src/screens/inbox/components/GiftedChatInboxComponent.tsx +411 -0
- package/src/screens/inbox/components/ServiceDialogsListItem.tsx +334 -172
- package/src/screens/inbox/components/SlackInput.tsx +23 -0
- package/src/screens/inbox/components/SlackMessageContainer/PaymentMessage.tsx +199 -0
- package/src/screens/inbox/components/SlackMessageContainer/SlackBubble.tsx +233 -23
- package/src/screens/inbox/components/SmartLoader.tsx +61 -0
- package/src/screens/inbox/components/SubscriptionHandler.tsx +41 -0
- package/src/screens/inbox/components/SupportServiceDialogsListItem.tsx +41 -24
- package/src/screens/inbox/components/ThreadsViewItem.tsx +177 -265
- package/src/screens/inbox/components/workflow/dialogs-list-item-xstate.ts +145 -0
- package/src/screens/inbox/components/workflow/service-dialogs-list-item-xstate.ts +159 -0
- package/src/screens/inbox/config/config.ts +2 -2
- package/src/screens/inbox/containers/ConversationView.tsx +2004 -698
- package/src/screens/inbox/containers/ConversationView.tsx.bk +1467 -0
- package/src/screens/inbox/containers/Dialogs.tsx +402 -196
- package/src/screens/inbox/containers/SupportServiceDialogs.tsx +2 -2
- package/src/screens/inbox/containers/ThreadConversationView.tsx +1337 -301
- package/src/screens/inbox/containers/ThreadsView.tsx +105 -186
- package/src/screens/inbox/containers/workflow/apollo/handleResult.ts +20 -0
- package/src/screens/inbox/containers/workflow/conversation-xstate.ts +313 -0
- package/src/screens/inbox/containers/workflow/dialogs-xstate.ts +196 -0
- package/src/screens/inbox/containers/workflow/thread-conversation-xstate.ts +401 -0
- package/src/screens/inbox/hooks/useInboxMessages.ts +34 -0
- package/src/screens/inbox/hooks/useSafeDialogThreadsMachine.ts +136 -0
- package/src/screens/inbox/index.ts +37 -0
- package/src/screens/inbox/machines/threadsMachine.ts +147 -0
- package/src/screens/inbox/workflow/dialog-threads-xstate.ts +163 -0
- package/lib/screens/inbox/components/DialogsListItem.js +0 -159
- package/lib/screens/inbox/components/DialogsListItem.js.map +0 -1
- package/lib/screens/inbox/components/ServiceDialogsListItem.js +0 -159
- package/lib/screens/inbox/components/ServiceDialogsListItem.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useMemo, useState } from 'react';
|
|
1
|
+
import React, { useMemo, useState, useCallback, useRef, useEffect } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Text,
|
|
4
4
|
Image,
|
|
@@ -15,14 +15,10 @@ import {
|
|
|
15
15
|
import { format, isToday, isYesterday } from 'date-fns';
|
|
16
16
|
import { useFocusEffect } from '@react-navigation/native';
|
|
17
17
|
import { IChannel, SortEnum, IUserAccount } from 'common';
|
|
18
|
-
import {
|
|
19
|
-
useMessagesQuery,
|
|
20
|
-
useOnChatMessageAddedSubscription,
|
|
21
|
-
OnChatMessageAddedDocument as CHAT_MESSAGE_ADDED,
|
|
22
|
-
useUserAccountQuery,
|
|
23
|
-
} from 'common/graphql';
|
|
18
|
+
import { CHAT_MESSAGE_ADDED, useMessagesQuery as useMessagesQueryFromInbox } from '../../../queries/inboxQueries';
|
|
24
19
|
import { startCase } from 'lodash-es';
|
|
25
20
|
import colors from 'tailwindcss/colors';
|
|
21
|
+
import { SubscriptionHandler } from './SubscriptionHandler';
|
|
26
22
|
|
|
27
23
|
const createdAtText = (value: string) => {
|
|
28
24
|
if (!value) return '';
|
|
@@ -42,8 +38,56 @@ export interface IDialogListItemProps {
|
|
|
42
38
|
selectedChannelId?: any;
|
|
43
39
|
channel?: any;
|
|
44
40
|
onOpen: (id: any, title: any) => void;
|
|
41
|
+
forceRefresh?: boolean;
|
|
42
|
+
visible?: boolean;
|
|
45
43
|
}
|
|
46
44
|
|
|
45
|
+
// LastMessage component definition
|
|
46
|
+
const LastMessageComponent = ({ title, lastMessage }) => {
|
|
47
|
+
const count = 30;
|
|
48
|
+
const channelTitle = title?.slice(0, count) + (title?.length > count ? '...' : '') || '';
|
|
49
|
+
|
|
50
|
+
// Define message display text
|
|
51
|
+
let displayMessage = 'No messages yet';
|
|
52
|
+
|
|
53
|
+
if (lastMessage) {
|
|
54
|
+
if (lastMessage.message && lastMessage.message.trim() !== '') {
|
|
55
|
+
// Show text message
|
|
56
|
+
displayMessage = lastMessage.message;
|
|
57
|
+
} else if (lastMessage.files?.data?.length > 0) {
|
|
58
|
+
// Show message with files
|
|
59
|
+
displayMessage = '📎 File attachment';
|
|
60
|
+
} else {
|
|
61
|
+
// Default for empty message
|
|
62
|
+
displayMessage = '(Empty message)';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Determine the date/time to display
|
|
67
|
+
const displayDate = lastMessage?.createdAt
|
|
68
|
+
? createdAtText(lastMessage.createdAt)
|
|
69
|
+
: lastMessage?.updatedAt
|
|
70
|
+
? createdAtText(lastMessage.updatedAt)
|
|
71
|
+
: '';
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<HStack space={'sm'} className="flex-1 justify-between">
|
|
75
|
+
<Box className="flex-[0.8]">
|
|
76
|
+
<Text color={colors.gray[600]} className="text-base text-wrap flex-wrap font-semibold">
|
|
77
|
+
{channelTitle}
|
|
78
|
+
</Text>
|
|
79
|
+
<Text color={colors.gray[600]} numberOfLines={1}>
|
|
80
|
+
{displayMessage}
|
|
81
|
+
</Text>
|
|
82
|
+
</Box>
|
|
83
|
+
|
|
84
|
+
<Box className="flex-[0.2]">
|
|
85
|
+
<Text color={colors.gray[500]}>{displayDate}</Text>
|
|
86
|
+
</Box>
|
|
87
|
+
</HStack>
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
|
|
47
91
|
/**
|
|
48
92
|
* TODO:
|
|
49
93
|
* - Get Reservation info: reservation date, status
|
|
@@ -51,121 +95,219 @@ export interface IDialogListItemProps {
|
|
|
51
95
|
*/
|
|
52
96
|
export const DialogsListItemComponent: React.FC<IDialogListItemProps> = function DialogsListItem({
|
|
53
97
|
currentUser,
|
|
54
|
-
// users,
|
|
55
98
|
selectedChannelId,
|
|
56
99
|
channel,
|
|
57
100
|
onOpen,
|
|
101
|
+
forceRefresh,
|
|
102
|
+
visible = true,
|
|
58
103
|
}) {
|
|
104
|
+
// Create a ref to track if component is mounted
|
|
105
|
+
const isMountedRef = useRef(true);
|
|
106
|
+
|
|
107
|
+
// Define parentId early to avoid linter errors
|
|
59
108
|
const parentId: any = null;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
109
|
+
|
|
110
|
+
// Simplified state - only keep loading state, rely on Apollo cache for data
|
|
111
|
+
const [loading, setLoading] = useState(false);
|
|
112
|
+
const [title, setTitle] = useState('');
|
|
113
|
+
|
|
114
|
+
// Only run queries/subscriptions if visible
|
|
115
|
+
const shouldQuery = !!channel?.id && visible;
|
|
116
|
+
|
|
117
|
+
// Memoize query variables to prevent unnecessary re-renders
|
|
118
|
+
const queryVariables = useMemo(
|
|
119
|
+
() => ({
|
|
68
120
|
channelId: channel?.id?.toString(),
|
|
69
121
|
parentId: parentId,
|
|
70
122
|
limit: 10,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
123
|
+
}),
|
|
124
|
+
[channel?.id, parentId],
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
// Optimized message processing function
|
|
128
|
+
const processMessagesData = useCallback((messagesData: any[]) => {
|
|
129
|
+
if (!messagesData?.length) return null;
|
|
130
|
+
|
|
131
|
+
// Sort messages and return the latest one
|
|
132
|
+
const sortedMessages = [...messagesData].sort(
|
|
133
|
+
(a, b) =>
|
|
134
|
+
new Date(b?.updatedAt || b?.createdAt).getTime() - new Date(a?.updatedAt || a?.createdAt).getTime(),
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
return sortedMessages[0];
|
|
138
|
+
}, []);
|
|
139
|
+
|
|
140
|
+
// Optimized refetch function - consolidated all refetch logic
|
|
141
|
+
const optimizedRefetch = useCallback(
|
|
142
|
+
async (reason: string = 'manual') => {
|
|
143
|
+
if (!shouldQuery || !channel?.id || !isMountedRef.current) return null;
|
|
144
|
+
|
|
145
|
+
console.log(`Optimized refetch triggered: ${reason} for channel ${channel?.id}`);
|
|
146
|
+
setLoading(true);
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
const result = await refetchMessages(queryVariables);
|
|
150
|
+
console.log(
|
|
151
|
+
`Refetch completed: ${reason}, messages count: ${result?.data?.messages?.data?.length || 0}`,
|
|
152
|
+
);
|
|
153
|
+
return result;
|
|
154
|
+
} catch (error) {
|
|
155
|
+
console.error(`Refetch error (${reason}):`, error);
|
|
156
|
+
return null;
|
|
157
|
+
} finally {
|
|
158
|
+
if (isMountedRef.current) {
|
|
159
|
+
setLoading(false);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
76
162
|
},
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
});
|
|
163
|
+
[shouldQuery, channel?.id, queryVariables],
|
|
164
|
+
);
|
|
80
165
|
|
|
166
|
+
// Query hooks for fetching messages - optimized configuration
|
|
81
167
|
const {
|
|
82
|
-
data:
|
|
83
|
-
loading:
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
168
|
+
data: messagesQuery,
|
|
169
|
+
loading: messageLoading,
|
|
170
|
+
refetch: refetchMessages,
|
|
171
|
+
subscribeToMore,
|
|
172
|
+
error,
|
|
173
|
+
} = useMessagesQueryFromInbox({
|
|
174
|
+
variables: queryVariables,
|
|
175
|
+
skip: !shouldQuery,
|
|
176
|
+
fetchPolicy: 'cache-first', // Changed from cache-and-network for better performance
|
|
177
|
+
nextFetchPolicy: 'cache-first',
|
|
178
|
+
notifyOnNetworkStatusChange: true,
|
|
179
|
+
errorPolicy: 'all', // Handle partial errors gracefully
|
|
180
|
+
onCompleted: (data) => {
|
|
181
|
+
// Simplified onCompleted - minimal processing
|
|
182
|
+
if (!shouldQuery || !data?.messages?.data) return;
|
|
183
|
+
|
|
184
|
+
console.log(`Query completed for channel ${channel?.id}, messages: ${data.messages.data.length}`);
|
|
185
|
+
},
|
|
186
|
+
onError: (error) => {
|
|
187
|
+
if (!shouldQuery) return;
|
|
188
|
+
console.error(`Query error for channel ${channel?.id}:`, error);
|
|
88
189
|
},
|
|
89
190
|
});
|
|
90
191
|
|
|
192
|
+
// Derived state from query data - use Apollo cache as single source of truth
|
|
193
|
+
const messages = useMemo(() => messagesQuery?.messages?.data || [], [messagesQuery]);
|
|
194
|
+
const lastMessage = useMemo(() => processMessagesData(messages), [messages, processMessagesData]);
|
|
195
|
+
|
|
196
|
+
// Set mounted state on mount/unmount
|
|
197
|
+
useEffect(() => {
|
|
198
|
+
isMountedRef.current = true;
|
|
199
|
+
return () => {
|
|
200
|
+
isMountedRef.current = false;
|
|
201
|
+
};
|
|
202
|
+
}, []);
|
|
203
|
+
|
|
204
|
+
// Optimized focus effect - single refetch with debouncing
|
|
205
|
+
const firstRenderRef = useRef(true);
|
|
91
206
|
useFocusEffect(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
refetchMessages({
|
|
95
|
-
channelId: channel?.id?.toString(),
|
|
96
|
-
parentId: parentId,
|
|
97
|
-
limit: 10,
|
|
98
|
-
// sort: {
|
|
99
|
-
// key: 'updatedAt',
|
|
100
|
-
// value: SortEnum.Desc,
|
|
101
|
-
// },
|
|
102
|
-
//limit: 25
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
return () => {
|
|
106
|
-
// Do something when the screen is unfocused
|
|
107
|
-
// Useful for cleanup functions
|
|
108
|
-
};
|
|
109
|
-
}, []),
|
|
110
|
-
);
|
|
207
|
+
useCallback(() => {
|
|
208
|
+
if (!channel?.id) return;
|
|
111
209
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
210
|
+
console.log('DialogsListItem focused for channel:', channel?.id);
|
|
211
|
+
|
|
212
|
+
// Skip refresh on first render
|
|
213
|
+
if (firstRenderRef.current) {
|
|
214
|
+
firstRenderRef.current = false;
|
|
215
|
+
return;
|
|
117
216
|
}
|
|
118
|
-
}
|
|
119
|
-
}, [messagesQuery]);
|
|
120
217
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
218
|
+
// Debounced refetch on focus
|
|
219
|
+
const timeoutId = setTimeout(() => {
|
|
220
|
+
optimizedRefetch('focus');
|
|
221
|
+
}, 100);
|
|
222
|
+
|
|
223
|
+
return () => clearTimeout(timeoutId);
|
|
224
|
+
}, [channel?.id, optimizedRefetch]),
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
// Simplified effect for force refresh
|
|
228
|
+
useEffect(() => {
|
|
229
|
+
if (forceRefresh && shouldQuery) {
|
|
230
|
+
const timeoutId = setTimeout(() => {
|
|
231
|
+
optimizedRefetch('force');
|
|
232
|
+
}, 50);
|
|
233
|
+
return () => clearTimeout(timeoutId);
|
|
124
234
|
}
|
|
125
|
-
|
|
126
|
-
const data = messages;
|
|
127
|
-
const filteredData: any = data?.filter((p: any) => p?.message !== '');
|
|
128
|
-
// return filteredData[0];
|
|
129
|
-
let filteredLastMessage =
|
|
130
|
-
filteredData && filteredData?.length
|
|
131
|
-
? filteredData?.reduce((a, b) => {
|
|
132
|
-
return new Date(a?.updatedAt) > new Date(b?.updatedAt) ? a : b;
|
|
133
|
-
}, []) ?? null
|
|
134
|
-
: null;
|
|
135
|
-
return filteredLastMessage;
|
|
136
|
-
//return data[data.length - 1];
|
|
137
|
-
}, [messages]);
|
|
235
|
+
}, [forceRefresh, shouldQuery, optimizedRefetch]);
|
|
138
236
|
|
|
237
|
+
// Channel members computation - optimized with better memoization
|
|
139
238
|
const channelMembers = useMemo(
|
|
140
239
|
() =>
|
|
141
240
|
channel?.members
|
|
142
|
-
?.filter((ch: any) => ch?.user?.id
|
|
143
|
-
?.map((m: any) => m?.user) ??
|
|
144
|
-
[currentUser, channel],
|
|
241
|
+
?.filter((ch: any) => ch?.user?.id !== currentUser?.id && ch?.user?.__typename === 'UserAccount')
|
|
242
|
+
?.map((m: any) => m?.user) ?? [],
|
|
243
|
+
[currentUser?.id, channel?.members],
|
|
145
244
|
);
|
|
146
245
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
246
|
+
// Set title when channel members change
|
|
247
|
+
useEffect(() => {
|
|
248
|
+
if (channelMembers.length > 0 && isMountedRef.current) {
|
|
249
|
+
const titleString =
|
|
250
|
+
channelMembers
|
|
251
|
+
?.map((u: any) => `${u?.givenName || ''} ${u?.familyName || ''}`.trim())
|
|
252
|
+
?.filter(Boolean)
|
|
253
|
+
?.join(', ') || '';
|
|
254
|
+
setTitle(titleString);
|
|
255
|
+
}
|
|
256
|
+
}, [channelMembers]);
|
|
153
257
|
|
|
258
|
+
// Compute title with proper truncation
|
|
259
|
+
const displayTitle = useMemo(() => {
|
|
154
260
|
const length = 30;
|
|
155
|
-
return
|
|
156
|
-
}, [
|
|
261
|
+
return title.length > length ? title.substring(0, length - 3) + '...' : title;
|
|
262
|
+
}, [title]);
|
|
263
|
+
|
|
264
|
+
// Combined loading state
|
|
265
|
+
const isLoading = loading || messageLoading;
|
|
157
266
|
|
|
158
267
|
return (
|
|
159
268
|
<Pressable
|
|
160
|
-
onPress={() =>
|
|
161
|
-
className="flex-1 border rounded-md
|
|
269
|
+
onPress={() => onOpen(channel?.id, displayTitle)}
|
|
270
|
+
className="flex-1 border-gray-200 rounded-md dark:border-gray-600 dark:bg-gray-700"
|
|
271
|
+
style={{ borderBottomWidth: 1, borderColor: '#e5e7eb', marginVertical: 0, paddingHorizontal: 10 }}
|
|
162
272
|
>
|
|
163
|
-
|
|
273
|
+
{/* Optimized subscription handler */}
|
|
274
|
+
<SubscriptionHandler
|
|
275
|
+
subscribeToMore={subscribeToMore}
|
|
276
|
+
document={CHAT_MESSAGE_ADDED}
|
|
277
|
+
variables={{ channelId: channel?.id?.toString() }}
|
|
278
|
+
enabled={shouldQuery}
|
|
279
|
+
updateQuery={(prev, { subscriptionData }) => {
|
|
280
|
+
if (!subscriptionData?.data?.chatMessageAdded || !isMountedRef.current) return prev;
|
|
281
|
+
|
|
282
|
+
const newMessage = subscriptionData.data.chatMessageAdded;
|
|
283
|
+
|
|
284
|
+
// Optimized cache update - check for duplicates more efficiently
|
|
285
|
+
const existingMessages = prev?.messages;
|
|
286
|
+
const messageExists = existingMessages?.data?.some((msg: any) => msg.id === newMessage.id);
|
|
287
|
+
|
|
288
|
+
if (!messageExists) {
|
|
289
|
+
return {
|
|
290
|
+
...prev,
|
|
291
|
+
messages: {
|
|
292
|
+
...existingMessages,
|
|
293
|
+
data: [...(existingMessages?.data || []), newMessage],
|
|
294
|
+
totalCount: (existingMessages?.totalCount || 0) + 1,
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
return prev;
|
|
299
|
+
}}
|
|
300
|
+
onError={(error) => {
|
|
301
|
+
console.error(`Subscription error for channel ${channel?.id}:`, error);
|
|
302
|
+
}}
|
|
303
|
+
/>
|
|
304
|
+
|
|
305
|
+
<HStack space={'md'} className="flex-1 w-[100%] py-3 items-center">
|
|
164
306
|
<Box className="flex-[0.1] items-start pl-3">
|
|
165
307
|
<AvatarGroup>
|
|
166
308
|
{channelMembers &&
|
|
167
309
|
channelMembers?.length > 0 &&
|
|
168
|
-
channelMembers?.slice(0,
|
|
310
|
+
channelMembers?.slice(0, 1)?.map((ch: any, i: Number) => (
|
|
169
311
|
<Avatar
|
|
170
312
|
key={'dialogs-list-' + i}
|
|
171
313
|
size={'sm'}
|
|
@@ -174,108 +316,47 @@ export const DialogsListItemComponent: React.FC<IDialogListItemProps> = function
|
|
|
174
316
|
}] z-[${i == 1 ? 5 : 1}]`}
|
|
175
317
|
>
|
|
176
318
|
<AvatarFallbackText>{startCase(ch?.username?.charAt(0))}</AvatarFallbackText>
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
319
|
+
{channelMembers?.length > 1 && (
|
|
320
|
+
<AvatarBadge
|
|
321
|
+
style={{
|
|
322
|
+
width: '100%',
|
|
323
|
+
height: '100%',
|
|
324
|
+
backgroundColor: '#e5e7eb',
|
|
325
|
+
borderRadius: 5,
|
|
326
|
+
}}
|
|
327
|
+
className="items-center justify-center bg-gray-200 rounded-md"
|
|
328
|
+
>
|
|
329
|
+
<Text style={{ fontSize: 12, fontWeight: 'bold', color: '#000' }}>
|
|
330
|
+
{channelMembers?.length}
|
|
331
|
+
</Text>
|
|
332
|
+
</AvatarBadge>
|
|
333
|
+
)}
|
|
184
334
|
{channelMembers?.length == 1 && (
|
|
185
|
-
|
|
335
|
+
<>
|
|
336
|
+
<AvatarImage
|
|
337
|
+
alt="user image"
|
|
338
|
+
style={{ borderRadius: 6, borderWidth: 2, borderColor: '#fff' }}
|
|
339
|
+
source={{
|
|
340
|
+
uri: ch?.picture,
|
|
341
|
+
}}
|
|
342
|
+
/>
|
|
343
|
+
<AvatarBadge style={{ width: 10, height: 10 }} />
|
|
344
|
+
</>
|
|
186
345
|
)}
|
|
187
346
|
</Avatar>
|
|
188
347
|
))}
|
|
189
348
|
</AvatarGroup>
|
|
190
349
|
</Box>
|
|
191
|
-
<Box className="flex-
|
|
192
|
-
{/* <HStack space={1} flex={1} direction={'row'} justifyContent={'center'} alignItems={'center'}>
|
|
193
|
-
<Box flex={0.8}>
|
|
194
|
-
<Text color="gray.600" fontSize="lg" flexWrap={'wrap'} fontWeight="semibold">
|
|
195
|
-
{title}
|
|
196
|
-
</Text>
|
|
197
|
-
<Text color="gray.600" noOfLines={1}>
|
|
198
|
-
{lastMessage?.message ?? ''}
|
|
199
|
-
</Text>
|
|
200
|
-
</Box>
|
|
201
|
-
|
|
202
|
-
<Box flex={0.2}>
|
|
203
|
-
<Text color="gray.500">{lastMessage ? createdAtText(lastMessage?.createdAt) : ''}</Text>
|
|
204
|
-
</Box>
|
|
205
|
-
</HStack> */}
|
|
350
|
+
<Box className="flex-1">
|
|
206
351
|
<LastMessageComponent
|
|
207
|
-
|
|
352
|
+
key={`last-msg-${lastMessage?.id || 'none'}-${messages.length}`}
|
|
353
|
+
title={displayTitle}
|
|
208
354
|
lastMessage={lastMessage}
|
|
209
|
-
channelId={channel?.id}
|
|
210
|
-
subscribeToNewMessages={() =>
|
|
211
|
-
subscribeToMore({
|
|
212
|
-
document: CHAT_MESSAGE_ADDED,
|
|
213
|
-
variables: {
|
|
214
|
-
channelId: channel.id?.toString(),
|
|
215
|
-
},
|
|
216
|
-
updateQuery: (prev, { subscriptionData }: any) => {
|
|
217
|
-
if (!subscriptionData.data) return prev;
|
|
218
|
-
const newMessage: any = subscriptionData?.data?.chatMessageAdded;
|
|
219
|
-
const existingMessages: any = prev?.messages;
|
|
220
|
-
const previousData = existingMessages?.data
|
|
221
|
-
? [...existingMessages.data, newMessage]
|
|
222
|
-
: [];
|
|
223
|
-
const totalMsgCount = existingMessages?.totalCount + 1;
|
|
224
|
-
const merged = {
|
|
225
|
-
...prev,
|
|
226
|
-
messages: {
|
|
227
|
-
...existingMessages,
|
|
228
|
-
data: previousData,
|
|
229
|
-
totalCount: totalMsgCount,
|
|
230
|
-
},
|
|
231
|
-
};
|
|
232
|
-
return merged;
|
|
233
|
-
},
|
|
234
|
-
})
|
|
235
|
-
}
|
|
236
355
|
/>
|
|
237
|
-
{/* <Text
|
|
238
|
-
flex={1}
|
|
239
|
-
color="gray.600"
|
|
240
|
-
p={0}
|
|
241
|
-
m={0}
|
|
242
|
-
w={'100%'}
|
|
243
|
-
justifyContent={''}
|
|
244
|
-
fontSize="lg"
|
|
245
|
-
fontWeight="semibold"
|
|
246
|
-
>
|
|
247
|
-
{title}
|
|
248
|
-
</Text> */}
|
|
249
|
-
{/* <Text flex={0.1} color="gray.600">
|
|
250
|
-
{lastMessage?.message ?? ''}
|
|
251
|
-
</Text> */}
|
|
252
356
|
</Box>
|
|
253
|
-
{/* <Text flex={0.2} color="gray.500">
|
|
254
|
-
{lastMessage ? createdAtText(lastMessage?.createdAt) : ''}
|
|
255
|
-
</Text> */}
|
|
256
357
|
</HStack>
|
|
257
358
|
</Pressable>
|
|
258
359
|
);
|
|
259
360
|
};
|
|
260
361
|
|
|
261
|
-
const LastMessageComponent = ({ subscribeToNewMessages, title, lastMessage, channelId }) => {
|
|
262
|
-
React.useEffect(() => subscribeToNewMessages(), [channelId]);
|
|
263
|
-
return (
|
|
264
|
-
<HStack space={'sm'} className="flex-1 justify-center items-center">
|
|
265
|
-
<Box className="flex-[0.8]">
|
|
266
|
-
<Text color={colors.gray[600]} className="text-lg flex-wrap font-semibold">
|
|
267
|
-
{title}
|
|
268
|
-
</Text>
|
|
269
|
-
<Text color={colors.gray[600]} numberOfLines={1}>
|
|
270
|
-
{lastMessage?.message ?? ''}
|
|
271
|
-
</Text>
|
|
272
|
-
</Box>
|
|
273
|
-
|
|
274
|
-
<Box className="flex-[0.2]">
|
|
275
|
-
<Text color={colors.gray[500]}>{lastMessage ? createdAtText(lastMessage?.createdAt) : ''}</Text>
|
|
276
|
-
</Box>
|
|
277
|
-
</HStack>
|
|
278
|
-
);
|
|
279
|
-
};
|
|
280
|
-
|
|
281
362
|
export const DialogsListItem = React.memo(DialogsListItemComponent);
|