@messenger-box/platform-mobile 10.0.3-alpha.7 → 10.0.3-alpha.74

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.
Files changed (98) hide show
  1. package/CHANGELOG.md +120 -0
  2. package/lib/compute.js +2 -3
  3. package/lib/compute.js.map +1 -1
  4. package/lib/index.js.map +1 -1
  5. package/lib/queries/inboxQueries.js +65 -0
  6. package/lib/queries/inboxQueries.js.map +1 -0
  7. package/lib/routes.json +2 -3
  8. package/lib/screens/inbox/DialogMessages.js +1 -1
  9. package/lib/screens/inbox/DialogMessages.js.map +1 -1
  10. package/lib/screens/inbox/DialogThreadMessages.js +4 -8
  11. package/lib/screens/inbox/DialogThreadMessages.js.map +1 -1
  12. package/lib/screens/inbox/DialogThreads.js +57 -12
  13. package/lib/screens/inbox/DialogThreads.js.map +1 -1
  14. package/lib/screens/inbox/Inbox.js +1 -1
  15. package/lib/screens/inbox/Inbox.js.map +1 -1
  16. package/lib/screens/inbox/components/CachedImage/consts.js +1 -1
  17. package/lib/screens/inbox/components/CachedImage/consts.js.map +1 -1
  18. package/lib/screens/inbox/components/CachedImage/index.js +168 -46
  19. package/lib/screens/inbox/components/CachedImage/index.js.map +1 -1
  20. package/lib/screens/inbox/components/DialogItem.js +169 -0
  21. package/lib/screens/inbox/components/DialogItem.js.map +1 -0
  22. package/lib/screens/inbox/components/GiftedChatInboxComponent.js +313 -0
  23. package/lib/screens/inbox/components/GiftedChatInboxComponent.js.map +1 -0
  24. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js +147 -31
  25. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js.map +1 -1
  26. package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js +6 -1
  27. package/lib/screens/inbox/components/SlackMessageContainer/SlackMessage.js.map +1 -1
  28. package/lib/screens/inbox/components/SubscriptionHandler.js +24 -0
  29. package/lib/screens/inbox/components/SubscriptionHandler.js.map +1 -0
  30. package/lib/screens/inbox/components/ThreadsViewItem.js +66 -55
  31. package/lib/screens/inbox/components/ThreadsViewItem.js.map +1 -1
  32. package/lib/screens/inbox/config/config.js +2 -2
  33. package/lib/screens/inbox/config/config.js.map +1 -1
  34. package/lib/screens/inbox/containers/ConversationView.js +1111 -434
  35. package/lib/screens/inbox/containers/ConversationView.js.map +1 -1
  36. package/lib/screens/inbox/containers/Dialogs.js +193 -80
  37. package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
  38. package/lib/screens/inbox/containers/ThreadConversationView.js +725 -216
  39. package/lib/screens/inbox/containers/ThreadConversationView.js.map +1 -1
  40. package/lib/screens/inbox/containers/ThreadsView.js +83 -50
  41. package/lib/screens/inbox/containers/ThreadsView.js.map +1 -1
  42. package/lib/screens/inbox/hooks/useInboxMessages.js +31 -0
  43. package/lib/screens/inbox/hooks/useInboxMessages.js.map +1 -0
  44. package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js +108 -0
  45. package/lib/screens/inbox/hooks/useSafeDialogThreadsMachine.js.map +1 -0
  46. package/lib/screens/inbox/workflow/dialog-threads-xstate.js +151 -0
  47. package/lib/screens/inbox/workflow/dialog-threads-xstate.js.map +1 -0
  48. package/package.json +4 -4
  49. package/src/compute.ts +5 -6
  50. package/src/index.ts +2 -0
  51. package/src/navigation/InboxNavigation.tsx +3 -3
  52. package/src/queries/inboxQueries.ts +299 -0
  53. package/src/queries/index.d.ts +2 -0
  54. package/src/queries/index.ts +1 -0
  55. package/src/screens/inbox/DialogMessages.tsx +1 -1
  56. package/src/screens/inbox/DialogThreadMessages.tsx +7 -14
  57. package/src/screens/inbox/DialogThreads.tsx +55 -61
  58. package/src/screens/inbox/Inbox.tsx +1 -1
  59. package/src/screens/inbox/components/Actionsheet.tsx +30 -0
  60. package/src/screens/inbox/components/CachedImage/consts.ts +4 -3
  61. package/src/screens/inbox/components/CachedImage/index.tsx +232 -61
  62. package/src/screens/inbox/components/DialogItem.tsx +306 -0
  63. package/src/screens/inbox/components/DialogsHeader.tsx +6 -13
  64. package/src/screens/inbox/components/DialogsListItem.tsx +262 -198
  65. package/src/screens/inbox/components/ExpandableInput.tsx +460 -0
  66. package/src/screens/inbox/components/ExpandableInputActionSheet.tsx +518 -0
  67. package/src/screens/inbox/components/GiftedChatInboxComponent.tsx +411 -0
  68. package/src/screens/inbox/components/ServiceDialogsListItem.tsx +337 -194
  69. package/src/screens/inbox/components/SlackInput.tsx +23 -0
  70. package/src/screens/inbox/components/SlackMessageContainer/SlackBubble.tsx +233 -23
  71. package/src/screens/inbox/components/SlackMessageContainer/SlackMessage.tsx +1 -1
  72. package/src/screens/inbox/components/SmartLoader.tsx +61 -0
  73. package/src/screens/inbox/components/SubscriptionHandler.tsx +41 -0
  74. package/src/screens/inbox/components/SupportServiceDialogsListItem.tsx +53 -55
  75. package/src/screens/inbox/components/ThreadsViewItem.tsx +178 -285
  76. package/src/screens/inbox/components/workflow/dialogs-list-item-xstate.ts +145 -0
  77. package/src/screens/inbox/components/workflow/service-dialogs-list-item-xstate.ts +159 -0
  78. package/src/screens/inbox/config/config.ts +2 -2
  79. package/src/screens/inbox/containers/ConversationView.tsx +1843 -702
  80. package/src/screens/inbox/containers/ConversationView.tsx.bk +1467 -0
  81. package/src/screens/inbox/containers/Dialogs.tsx +402 -204
  82. package/src/screens/inbox/containers/SupportServiceDialogs.tsx +4 -4
  83. package/src/screens/inbox/containers/ThreadConversationView.tsx +1350 -319
  84. package/src/screens/inbox/containers/ThreadsView.tsx +105 -193
  85. package/src/screens/inbox/containers/workflow/apollo/handleResult.ts +20 -0
  86. package/src/screens/inbox/containers/workflow/conversation-xstate.ts +313 -0
  87. package/src/screens/inbox/containers/workflow/dialogs-xstate.ts +196 -0
  88. package/src/screens/inbox/containers/workflow/thread-conversation-xstate.ts +401 -0
  89. package/src/screens/inbox/hooks/useInboxMessages.ts +34 -0
  90. package/src/screens/inbox/hooks/useSafeDialogThreadsMachine.ts +136 -0
  91. package/src/screens/inbox/index.ts +37 -0
  92. package/src/screens/inbox/machines/threadsMachine.ts +147 -0
  93. package/src/screens/inbox/workflow/dialog-threads-xstate.ts +163 -0
  94. package/tsconfig.json +11 -54
  95. package/lib/screens/inbox/components/DialogsListItem.js +0 -171
  96. package/lib/screens/inbox/components/DialogsListItem.js.map +0 -1
  97. package/lib/screens/inbox/components/ServiceDialogsListItem.js +0 -171
  98. 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,13 +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/lib/generated/generated.js';
18
+ import { CHAT_MESSAGE_ADDED, useMessagesQuery as useMessagesQueryFromInbox } from '../../../queries/inboxQueries';
24
19
  import { startCase } from 'lodash-es';
20
+ import colors from 'tailwindcss/colors';
21
+ import { SubscriptionHandler } from './SubscriptionHandler';
25
22
 
26
23
  const createdAtText = (value: string) => {
27
24
  if (!value) return '';
@@ -41,8 +38,56 @@ export interface IDialogListItemProps {
41
38
  selectedChannelId?: any;
42
39
  channel?: any;
43
40
  onOpen: (id: any, title: any) => void;
41
+ forceRefresh?: boolean;
42
+ visible?: boolean;
44
43
  }
45
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
+
46
91
  /**
47
92
  * TODO:
48
93
  * - Get Reservation info: reservation date, status
@@ -50,249 +95,268 @@ export interface IDialogListItemProps {
50
95
  */
51
96
  export const DialogsListItemComponent: React.FC<IDialogListItemProps> = function DialogsListItem({
52
97
  currentUser,
53
- // users,
54
98
  selectedChannelId,
55
99
  channel,
56
100
  onOpen,
101
+ forceRefresh,
102
+ visible = true,
57
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
58
108
  const parentId: any = null;
59
- const [messages, setMessages] = useState<any>([]);
60
- const {
61
- data: messagesQuery,
62
- loading: messageLoading,
63
- refetch: refetchMessages,
64
- subscribeToMore,
65
- } = useMessagesQuery({
66
- variables: {
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
+ () => ({
67
120
  channelId: channel?.id?.toString(),
68
121
  parentId: parentId,
69
122
  limit: 10,
70
- // sort: {
71
- // key: 'updatedAt',
72
- // value: SortEnum.Desc,
73
- // },
74
- //limit: 25,
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
+ }
75
162
  },
76
- fetchPolicy: 'cache-and-network',
77
- refetchWritePolicy: 'merge',
78
- });
163
+ [shouldQuery, channel?.id, queryVariables],
164
+ );
79
165
 
166
+ // Query hooks for fetching messages - optimized configuration
80
167
  const {
81
- data: newMessage,
82
- loading: newMsgLoading,
83
- error: newMsgError,
84
- }: any = useOnChatMessageAddedSubscription({
85
- variables: {
86
- channelId: channel?.id?.toString(),
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);
87
189
  },
88
190
  });
89
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);
90
206
  useFocusEffect(
91
- React.useCallback(() => {
92
- // Do something when the screen is focused
93
- refetchMessages({
94
- channelId: channel?.id?.toString(),
95
- parentId: parentId,
96
- limit: 10,
97
- // sort: {
98
- // key: 'updatedAt',
99
- // value: SortEnum.Desc,
100
- // },
101
- //limit: 25
102
- });
103
-
104
- return () => {
105
- // Do something when the screen is unfocused
106
- // Useful for cleanup functions
107
- };
108
- }, []),
109
- );
207
+ useCallback(() => {
208
+ if (!channel?.id) return;
209
+
210
+ console.log('DialogsListItem focused for channel:', channel?.id);
110
211
 
111
- React.useEffect(() => {
112
- if (messagesQuery) {
113
- if (messagesQuery?.messages?.data?.length) {
114
- const msg = messagesQuery?.messages?.data;
115
- setMessages((pre: any[]) => [...pre, ...msg]);
212
+ // Skip refresh on first render
213
+ if (firstRenderRef.current) {
214
+ firstRenderRef.current = false;
215
+ return;
116
216
  }
117
- }
118
- }, [messagesQuery]);
119
217
 
120
- const lastMessage = useMemo(() => {
121
- if (!messages?.length) {
122
- return null;
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);
123
234
  }
124
- // const { data } = messagesQuery.messages;
125
- const data = messages;
126
- const filteredData: any = data?.filter((p: any) => p?.message !== '');
127
- // return filteredData[0];
128
- let filteredLastMessage =
129
- filteredData && filteredData?.length
130
- ? filteredData?.reduce((a, b) => {
131
- return new Date(a?.updatedAt) > new Date(b?.updatedAt) ? a : b;
132
- }, []) ?? null
133
- : null;
134
- return filteredLastMessage;
135
- //return data[data.length - 1];
136
- }, [messages]);
235
+ }, [forceRefresh, shouldQuery, optimizedRefetch]);
137
236
 
237
+ // Channel members computation - optimized with better memoization
138
238
  const channelMembers = useMemo(
139
239
  () =>
140
240
  channel?.members
141
- ?.filter((ch: any) => ch?.user?.id != currentUser?.id && ch?.user?.__typename == 'UserAccount')
142
- ?.map((m: any) => m?.user) ?? null,
143
- [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],
144
244
  );
145
245
 
146
- const title = useMemo(() => {
147
- const titleString =
148
- channelMembers
149
- ?.map((u: any) => u?.givenName + ' ' + (u?.familyName ?? ''))
150
- ?.filter((mu: any) => mu)
151
- ?.join(', ') ?? '';
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]);
152
257
 
258
+ // Compute title with proper truncation
259
+ const displayTitle = useMemo(() => {
153
260
  const length = 30;
154
- return titleString.length > length ? titleString.substring(0, length - 3) + '...' : titleString;
155
- }, [channelMembers]);
261
+ return title.length > length ? title.substring(0, length - 3) + '...' : title;
262
+ }, [title]);
263
+
264
+ // Combined loading state
265
+ const isLoading = loading || messageLoading;
156
266
 
157
267
  return (
158
268
  <Pressable
159
- onPress={() => channel?.id !== selectedChannelId && onOpen(channel?.id, title)}
160
- borderWidth={'$1'}
161
- borderRadius={'$md'}
162
- borderColor={'$trueGray200'}
163
- flex={1}
164
- $dark-borderColor="$coolGray600"
165
- $dark-backgroundColor="$trueGray700"
166
- $light-backgroundColor="$trueGray50"
167
- $light-borderColor="$trueGray200"
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 }}
168
272
  >
169
- <HStack
170
- // px={2}
171
- // pl={3}
172
- py={'$3'}
173
- space={'sm'}
174
- w={'100%'}
175
- flex={1}
176
- // direction={'row'}
177
- justifyContent={'space-between'}
178
- alignItems={'center'}
179
- >
180
- <Box flex={0.1} alignItems={'flex-start'} pl={'$3'}>
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">
306
+ <Box className="flex-[0.1] items-start pl-3">
181
307
  <AvatarGroup>
182
308
  {channelMembers &&
183
309
  channelMembers?.length > 0 &&
184
- channelMembers?.slice(0, 2)?.map((ch: any, i: Number) => (
310
+ channelMembers?.slice(0, 1)?.map((ch: any, i: Number) => (
185
311
  <Avatar
186
312
  key={'dialogs-list-' + i}
187
- bg={'transparent'}
188
313
  size={'sm'}
189
- top={i == 1 ? '$4' : '$0'}
190
- right={i == 1 ? '-$2' : '$0'}
191
- zIndex={i == 1 ? 5 : 1}
314
+ className={`bg-transparent top-[${i == 1 ? '4' : '0'}] right-[${
315
+ i == 1 ? '-2' : '0'
316
+ }] z-[${i == 1 ? 5 : 1}]`}
192
317
  >
193
318
  <AvatarFallbackText>{startCase(ch?.username?.charAt(0))}</AvatarFallbackText>
194
- <AvatarImage
195
- alt="user image"
196
- style={{ borderRadius: 6, borderWidth: 2, borderColor: '#fff' }}
197
- source={{
198
- uri: ch?.picture,
199
- }}
200
- />
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
+ )}
201
334
  {channelMembers?.length == 1 && (
202
- <AvatarBadge style={{ width: 10, height: 10 }} bg="$green800" />
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
+ </>
203
345
  )}
204
346
  </Avatar>
205
347
  ))}
206
348
  </AvatarGroup>
207
349
  </Box>
208
- <Box flex={0.9}>
209
- {/* <HStack space={1} flex={1} direction={'row'} justifyContent={'center'} alignItems={'center'}>
210
- <Box flex={0.8}>
211
- <Text color="gray.600" fontSize="lg" flexWrap={'wrap'} fontWeight="semibold">
212
- {title}
213
- </Text>
214
- <Text color="gray.600" noOfLines={1}>
215
- {lastMessage?.message ?? ''}
216
- </Text>
217
- </Box>
218
-
219
- <Box flex={0.2}>
220
- <Text color="gray.500">{lastMessage ? createdAtText(lastMessage?.createdAt) : ''}</Text>
221
- </Box>
222
- </HStack> */}
350
+ <Box className="flex-1">
223
351
  <LastMessageComponent
224
- title={title}
352
+ key={`last-msg-${lastMessage?.id || 'none'}-${messages.length}`}
353
+ title={displayTitle}
225
354
  lastMessage={lastMessage}
226
- channelId={channel?.id}
227
- subscribeToNewMessages={() =>
228
- subscribeToMore({
229
- document: CHAT_MESSAGE_ADDED,
230
- variables: {
231
- channelId: channel.id?.toString(),
232
- },
233
- updateQuery: (prev, { subscriptionData }: any) => {
234
- if (!subscriptionData.data) return prev;
235
- const newMessage: any = subscriptionData?.data?.chatMessageAdded;
236
- const existingMessages: any = prev?.messages;
237
- const previousData = existingMessages?.data
238
- ? [...existingMessages.data, newMessage]
239
- : [];
240
- const totalMsgCount = existingMessages?.totalCount + 1;
241
- const merged = {
242
- ...prev,
243
- messages: {
244
- ...existingMessages,
245
- data: previousData,
246
- totalCount: totalMsgCount,
247
- },
248
- };
249
- return merged;
250
- },
251
- })
252
- }
253
355
  />
254
- {/* <Text
255
- flex={1}
256
- color="gray.600"
257
- p={0}
258
- m={0}
259
- w={'100%'}
260
- justifyContent={''}
261
- fontSize="lg"
262
- fontWeight="semibold"
263
- >
264
- {title}
265
- </Text> */}
266
- {/* <Text flex={0.1} color="gray.600">
267
- {lastMessage?.message ?? ''}
268
- </Text> */}
269
356
  </Box>
270
- {/* <Text flex={0.2} color="gray.500">
271
- {lastMessage ? createdAtText(lastMessage?.createdAt) : ''}
272
- </Text> */}
273
357
  </HStack>
274
358
  </Pressable>
275
359
  );
276
360
  };
277
361
 
278
- const LastMessageComponent = ({ subscribeToNewMessages, title, lastMessage, channelId }) => {
279
- React.useEffect(() => subscribeToNewMessages(), [channelId]);
280
- return (
281
- <HStack space={'sm'} flex={1} justifyContent={'center'} alignItems={'center'}>
282
- <Box flex={0.8}>
283
- <Text color="$trueGray600" fontSize="$lg" flexWrap={'wrap'} fontWeight="$semibold">
284
- {title}
285
- </Text>
286
- <Text color="$trueGray600" numberOfLines={1}>
287
- {lastMessage?.message ?? ''}
288
- </Text>
289
- </Box>
290
-
291
- <Box flex={0.2}>
292
- <Text color="$trueGray500">{lastMessage ? createdAtText(lastMessage?.createdAt) : ''}</Text>
293
- </Box>
294
- </HStack>
295
- );
296
- };
297
-
298
362
  export const DialogsListItem = React.memo(DialogsListItemComponent);