@messenger-box/platform-mobile 10.0.3-alpha.36 → 10.0.3-alpha.37
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 +4 -0
- package/lib/screens/inbox/components/CachedImage/index.js +125 -93
- package/lib/screens/inbox/components/CachedImage/index.js.map +1 -1
- package/lib/screens/inbox/components/DialogsListItem.js +75 -271
- package/lib/screens/inbox/components/DialogsListItem.js.map +1 -1
- package/lib/screens/inbox/components/ServiceDialogsListItem.js +184 -415
- package/lib/screens/inbox/components/ServiceDialogsListItem.js.map +1 -1
- package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js +0 -2
- package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js.map +1 -1
- package/lib/screens/inbox/containers/ConversationView.js +478 -944
- package/lib/screens/inbox/containers/ConversationView.js.map +1 -1
- package/lib/screens/inbox/containers/Dialogs.js +212 -628
- package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
- package/lib/screens/inbox/containers/ThreadConversationView.js +409 -1364
- package/lib/screens/inbox/containers/ThreadConversationView.js.map +1 -1
- package/package.json +3 -3
- package/src/screens/inbox/components/CachedImage/index.tsx +191 -140
- package/src/screens/inbox/components/DialogsListItem.tsx +104 -368
- package/src/screens/inbox/components/ServiceDialogsListItem.tsx +69 -377
- package/src/screens/inbox/components/SlackMessageContainer/SlackBubble.tsx +2 -4
- package/src/screens/inbox/containers/ConversationView.tsx +660 -1060
- package/src/screens/inbox/containers/ConversationView.tsx.bk +1467 -0
- package/src/screens/inbox/containers/Dialogs.tsx +301 -763
- package/src/screens/inbox/containers/ThreadConversationView.tsx +661 -1887
- package/lib/screens/inbox/components/workflow/dialogs-list-item-xstate.js +0 -175
- package/lib/screens/inbox/components/workflow/dialogs-list-item-xstate.js.map +0 -1
- package/lib/screens/inbox/components/workflow/service-dialogs-list-item-xstate.js +0 -191
- package/lib/screens/inbox/components/workflow/service-dialogs-list-item-xstate.js.map +0 -1
- package/lib/screens/inbox/containers/workflow/conversation-xstate.js +0 -380
- package/lib/screens/inbox/containers/workflow/conversation-xstate.js.map +0 -1
- package/lib/screens/inbox/containers/workflow/dialogs-xstate.js +0 -211
- package/lib/screens/inbox/containers/workflow/dialogs-xstate.js.map +0 -1
- package/lib/screens/inbox/containers/workflow/thread-conversation-xstate.js +0 -438
- package/lib/screens/inbox/containers/workflow/thread-conversation-xstate.js.map +0 -1
|
@@ -24,7 +24,6 @@ import {
|
|
|
24
24
|
} from 'common/graphql';
|
|
25
25
|
import { startCase } from 'lodash-es';
|
|
26
26
|
import colors from 'tailwindcss/colors';
|
|
27
|
-
import { serviceDialogsListItemXstate, Actions, BaseState } from './workflow/service-dialogs-list-item-xstate';
|
|
28
27
|
|
|
29
28
|
// Helper function to safely create a Date object
|
|
30
29
|
const safeDate = (dateValue) => {
|
|
@@ -68,223 +67,58 @@ export interface IDialogListItemProps {
|
|
|
68
67
|
role: any;
|
|
69
68
|
}
|
|
70
69
|
|
|
71
|
-
//
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
interface SafeStateType {
|
|
75
|
-
context: {
|
|
76
|
-
channelId: string | null;
|
|
77
|
-
currentUser: any;
|
|
78
|
-
threadMessages: any[];
|
|
79
|
-
loading: boolean;
|
|
80
|
-
error: string | null;
|
|
81
|
-
title: string;
|
|
82
|
-
role: string;
|
|
83
|
-
servicePostParentId: string | null;
|
|
84
|
-
lastMessage: any;
|
|
85
|
-
};
|
|
86
|
-
value: string;
|
|
87
|
-
matches?: (stateValue: string) => boolean;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Initialize state with default values to prevent undefined errors
|
|
91
|
-
const [state, setState] = useState<SafeStateType>({
|
|
92
|
-
context: {
|
|
93
|
-
channelId: null,
|
|
94
|
-
currentUser: null,
|
|
95
|
-
threadMessages: [],
|
|
96
|
-
loading: false,
|
|
97
|
-
error: null,
|
|
98
|
-
title: '',
|
|
99
|
-
role: '',
|
|
100
|
-
servicePostParentId: null,
|
|
101
|
-
lastMessage: null,
|
|
102
|
-
},
|
|
103
|
-
value: BaseState.Idle,
|
|
104
|
-
matches: (stateValue) => stateValue === BaseState.Idle,
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
// Implement a send function that updates state safely
|
|
108
|
-
const send = useCallback((event) => {
|
|
109
|
-
try {
|
|
110
|
-
// Handle specific events manually
|
|
111
|
-
if (event.type === Actions.INITIAL_CONTEXT) {
|
|
112
|
-
setState((prev) => ({
|
|
113
|
-
...prev,
|
|
114
|
-
context: {
|
|
115
|
-
...prev.context,
|
|
116
|
-
channelId: event.data?.channelId || null,
|
|
117
|
-
currentUser: event.data?.currentUser || null,
|
|
118
|
-
role: event.data?.role || null,
|
|
119
|
-
loading: true,
|
|
120
|
-
},
|
|
121
|
-
value: BaseState.FetchingThreadMessages,
|
|
122
|
-
}));
|
|
123
|
-
} else if (event.type === Actions.UPDATE_THREAD_MESSAGES) {
|
|
124
|
-
setState((prev) => {
|
|
125
|
-
if (event.data?.threadMessages) {
|
|
126
|
-
// Handling bulk messages (initial load)
|
|
127
|
-
// If a direct last message was provided (from subscription), use it
|
|
128
|
-
if (event.data?.directLastMessage) {
|
|
129
|
-
console.log('Using direct last message from event:', {
|
|
130
|
-
id: event.data.directLastMessage.id,
|
|
131
|
-
message: event.data.directLastMessage.message?.substring(0, 20) + '...',
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
...prev,
|
|
136
|
-
context: {
|
|
137
|
-
...prev.context,
|
|
138
|
-
threadMessages: event.data.threadMessages,
|
|
139
|
-
lastMessage: event.data.directLastMessage,
|
|
140
|
-
loading: false,
|
|
141
|
-
},
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return {
|
|
146
|
-
...prev,
|
|
147
|
-
context: {
|
|
148
|
-
...prev.context,
|
|
149
|
-
threadMessages: event.data.threadMessages,
|
|
150
|
-
lastMessage: computeLastMessage(event.data.threadMessages),
|
|
151
|
-
loading: false,
|
|
152
|
-
},
|
|
153
|
-
};
|
|
154
|
-
} else if (event.data?.message) {
|
|
155
|
-
// Handling single message (from subscription)
|
|
156
|
-
const newMessage = event.data.message;
|
|
157
|
-
const updatedMessages = [...prev.context.threadMessages, newMessage];
|
|
158
|
-
|
|
159
|
-
// Use the new message directly as the last message
|
|
160
|
-
// This ensures immediate update on subscription
|
|
161
|
-
console.log('Setting new message as lastMessage from subscription:', {
|
|
162
|
-
id: newMessage.id,
|
|
163
|
-
message: newMessage.message?.substring(0, 20) + '...',
|
|
164
|
-
date: newMessage.createdAt || newMessage.updatedAt,
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
...prev,
|
|
169
|
-
context: {
|
|
170
|
-
...prev.context,
|
|
171
|
-
threadMessages: updatedMessages,
|
|
172
|
-
lastMessage: newMessage, // Use the new message directly
|
|
173
|
-
loading: false,
|
|
174
|
-
},
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
return prev;
|
|
178
|
-
});
|
|
179
|
-
} else if (event.type === Actions.SET_TITLE) {
|
|
180
|
-
setState((prev) => ({
|
|
181
|
-
...prev,
|
|
182
|
-
context: {
|
|
183
|
-
...prev.context,
|
|
184
|
-
title: event.data?.title || '',
|
|
185
|
-
},
|
|
186
|
-
}));
|
|
187
|
-
} else if (event.type === Actions.SET_SERVICE_POST_PARENT_ID) {
|
|
188
|
-
setState((prev) => ({
|
|
189
|
-
...prev,
|
|
190
|
-
context: {
|
|
191
|
-
...prev.context,
|
|
192
|
-
servicePostParentId: event.data?.servicePostParentId || null,
|
|
193
|
-
},
|
|
194
|
-
}));
|
|
195
|
-
} else if (event.type === Actions.START_LOADING) {
|
|
196
|
-
setState((prev) => ({
|
|
197
|
-
...prev,
|
|
198
|
-
context: {
|
|
199
|
-
...prev.context,
|
|
200
|
-
loading: true,
|
|
201
|
-
},
|
|
202
|
-
}));
|
|
203
|
-
} else if (event.type === Actions.STOP_LOADING) {
|
|
204
|
-
setState((prev) => ({
|
|
205
|
-
...prev,
|
|
206
|
-
context: {
|
|
207
|
-
...prev.context,
|
|
208
|
-
loading: false,
|
|
209
|
-
},
|
|
210
|
-
}));
|
|
211
|
-
}
|
|
212
|
-
} catch (error) {
|
|
213
|
-
console.error('Error sending event to state machine:', error);
|
|
214
|
-
}
|
|
215
|
-
}, []);
|
|
216
|
-
|
|
217
|
-
// Helper function to compute the last message from a list of messages
|
|
218
|
-
const computeLastMessage = (threadMessages) => {
|
|
219
|
-
if (!threadMessages || !threadMessages.length) return null;
|
|
220
|
-
|
|
221
|
-
// Extract the post and replies from thread messages
|
|
222
|
-
let posts = [];
|
|
223
|
-
let replies = [];
|
|
70
|
+
// Helper function to compute the last message from a list of messages
|
|
71
|
+
const computeLastMessage = (threadMessages) => {
|
|
72
|
+
if (!threadMessages || !threadMessages.length) return null;
|
|
224
73
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
74
|
+
// Extract the post and replies from thread messages
|
|
75
|
+
let posts = [];
|
|
76
|
+
let replies = [];
|
|
228
77
|
|
|
229
|
-
|
|
230
|
-
|
|
78
|
+
// Helper function to check if a message is an image or contains only image content
|
|
79
|
+
const isTextMessage = (msg) => {
|
|
80
|
+
if (!msg) return false;
|
|
231
81
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
msg.message.includes('<img') ||
|
|
235
|
-
msg.message.includes('[Image]') ||
|
|
236
|
-
msg.message.includes('![') ||
|
|
237
|
-
(/\.(jpeg|jpg|gif|png|bmp|webp)/i.test(msg.message) &&
|
|
238
|
-
(msg.message.includes('http') || msg.message.includes('/images/')));
|
|
239
|
-
|
|
240
|
-
// Return true only for text messages (not image messages)
|
|
241
|
-
return !isImageMessage;
|
|
242
|
-
};
|
|
82
|
+
// If message is empty or only contains image-specific markers, ignore it
|
|
83
|
+
if (!msg.message || msg.message === '') return false;
|
|
243
84
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
});
|
|
85
|
+
// Check if message looks like an image URL or reference
|
|
86
|
+
const isImageMessage =
|
|
87
|
+
msg.message.includes('<img') ||
|
|
88
|
+
msg.message.includes('[Image]') ||
|
|
89
|
+
msg.message.includes('![') ||
|
|
90
|
+
(/\.(jpeg|jpg|gif|png|bmp|webp)/i.test(msg.message) &&
|
|
91
|
+
(msg.message.includes('http') || msg.message.includes('/images/')));
|
|
252
92
|
|
|
253
|
-
//
|
|
254
|
-
|
|
255
|
-
|
|
93
|
+
// Return true only for text messages (not image messages)
|
|
94
|
+
return !isImageMessage;
|
|
95
|
+
};
|
|
256
96
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
97
|
+
threadMessages.forEach((thread) => {
|
|
98
|
+
if (thread?.post && isTextMessage(thread.post)) {
|
|
99
|
+
posts.push(thread.post);
|
|
100
|
+
}
|
|
101
|
+
if (thread?.replies?.length) {
|
|
102
|
+
replies = [...replies, ...thread.replies.filter((r) => isTextMessage(r))];
|
|
103
|
+
}
|
|
104
|
+
});
|
|
261
105
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
106
|
+
// Combine and sort all messages
|
|
107
|
+
const allMessages = [...posts, ...replies];
|
|
108
|
+
if (!allMessages.length) return null;
|
|
265
109
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
110
|
+
// Return the most recent message - use safe date comparison
|
|
111
|
+
return allMessages.reduce((a, b) => {
|
|
112
|
+
const dateA = safeDate(a?.createdAt);
|
|
113
|
+
const dateB = safeDate(b?.createdAt);
|
|
269
114
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
return
|
|
273
|
-
...state,
|
|
274
|
-
matches: (stateValue) => {
|
|
275
|
-
try {
|
|
276
|
-
return state.value === stateValue;
|
|
277
|
-
} catch (error) {
|
|
278
|
-
console.error(`Error in matches function:`, error);
|
|
279
|
-
return false;
|
|
280
|
-
}
|
|
281
|
-
},
|
|
282
|
-
};
|
|
283
|
-
}, [state]);
|
|
115
|
+
// If either date is invalid, prefer the message with valid date
|
|
116
|
+
if (!dateA) return b;
|
|
117
|
+
if (!dateB) return a;
|
|
284
118
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
}
|
|
119
|
+
return dateA > dateB ? a : b;
|
|
120
|
+
}, allMessages[0]);
|
|
121
|
+
};
|
|
288
122
|
|
|
289
123
|
const ServiceChannelWithLastMessage = React.memo(
|
|
290
124
|
({ channel, lastMessage, subscribeToNewMessages, subscribeToChatMessages }: any) => {
|
|
@@ -397,35 +231,11 @@ export const ServiceDialogsListItemComponent: React.FC<IDialogListItemProps> = f
|
|
|
397
231
|
}) {
|
|
398
232
|
// Create a ref to track if component is mounted
|
|
399
233
|
const isMountedRef = useRef(true);
|
|
400
|
-
|
|
401
|
-
const [state, send] = useSafeMachine(serviceDialogsListItemXstate);
|
|
402
|
-
|
|
403
|
-
const safeContextProperty = useCallback(
|
|
404
|
-
(property, defaultValue = null) => {
|
|
405
|
-
try {
|
|
406
|
-
return state?.context?.[property] ?? defaultValue;
|
|
407
|
-
} catch (error) {
|
|
408
|
-
console.error(`Error accessing state.context.${property}:`, error);
|
|
409
|
-
return defaultValue;
|
|
410
|
-
}
|
|
411
|
-
},
|
|
412
|
-
[state],
|
|
413
|
-
);
|
|
414
|
-
|
|
415
|
-
const safeSend = useCallback(
|
|
416
|
-
(event) => {
|
|
417
|
-
try {
|
|
418
|
-
send(event);
|
|
419
|
-
} catch (error) {
|
|
420
|
-
console.error('Error sending event to state machine:', error, event);
|
|
421
|
-
}
|
|
422
|
-
},
|
|
423
|
-
[send],
|
|
424
|
-
);
|
|
234
|
+
const [subscriptionsTimestamp, setSubscriptionsTimestamp] = useState(Date.now());
|
|
425
235
|
|
|
426
236
|
// Query for thread messages
|
|
427
237
|
const {
|
|
428
|
-
data:
|
|
238
|
+
data: threadMessagesData,
|
|
429
239
|
loading: threadMessageLoading,
|
|
430
240
|
error,
|
|
431
241
|
refetch: refetchThreadMessages,
|
|
@@ -448,71 +258,28 @@ export const ServiceDialogsListItemComponent: React.FC<IDialogListItemProps> = f
|
|
|
448
258
|
},
|
|
449
259
|
});
|
|
450
260
|
|
|
451
|
-
//
|
|
452
|
-
|
|
453
|
-
if (channel?.id) {
|
|
454
|
-
safeSend({
|
|
455
|
-
type: Actions.INITIAL_CONTEXT,
|
|
456
|
-
data: {
|
|
457
|
-
channelId: channel?.id?.toString(),
|
|
458
|
-
currentUser,
|
|
459
|
-
role,
|
|
460
|
-
},
|
|
461
|
-
});
|
|
261
|
+
// Extract threadMessages data for easier access
|
|
262
|
+
const threadMessages = threadMessagesData?.threadMessages?.data || [];
|
|
462
263
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
264
|
+
// Calculate lastMessage directly from threadMessages
|
|
265
|
+
const lastMessage = useMemo(() => {
|
|
266
|
+
return computeLastMessage(threadMessages);
|
|
267
|
+
}, [threadMessages]);
|
|
268
|
+
|
|
269
|
+
// Calculate servicePostParentId based on lastMessage
|
|
270
|
+
const servicePostParentId = useMemo(() => {
|
|
271
|
+
if (!lastMessage) return null;
|
|
272
|
+
return lastMessage?.parentId ? lastMessage?.parentId : lastMessage?.id;
|
|
273
|
+
}, [lastMessage]);
|
|
470
274
|
|
|
275
|
+
// Handle component unmount
|
|
276
|
+
React.useEffect(() => {
|
|
471
277
|
return () => {
|
|
472
278
|
isMountedRef.current = false;
|
|
473
279
|
};
|
|
474
|
-
}, [
|
|
475
|
-
|
|
476
|
-
// Update state when thread messages are loaded or refreshed
|
|
477
|
-
React.useEffect(() => {
|
|
478
|
-
if (threadMessages && isMountedRef.current) {
|
|
479
|
-
console.log(
|
|
480
|
-
`Updating thread messages for channel ${channel?.id}, count:`,
|
|
481
|
-
threadMessages?.threadMessages?.data?.length || 0,
|
|
482
|
-
);
|
|
483
|
-
|
|
484
|
-
safeSend({
|
|
485
|
-
type: Actions.UPDATE_THREAD_MESSAGES,
|
|
486
|
-
data: {
|
|
487
|
-
threadMessages: threadMessages?.threadMessages?.data || [],
|
|
488
|
-
},
|
|
489
|
-
});
|
|
490
|
-
}
|
|
491
|
-
}, [threadMessages, refreshing, channel?.id, safeSend]);
|
|
492
|
-
|
|
493
|
-
// Use computed values from state
|
|
494
|
-
const lastMessage = safeContextProperty('lastMessage', null);
|
|
495
|
-
const servicePostParentId = safeContextProperty('servicePostParentId', null);
|
|
496
|
-
|
|
497
|
-
// Update servicePostParentId when lastMessage changes
|
|
498
|
-
React.useEffect(() => {
|
|
499
|
-
if (lastMessage) {
|
|
500
|
-
const sParentId = lastMessage?.parentId ? lastMessage?.parentId : lastMessage?.id;
|
|
501
|
-
|
|
502
|
-
if (sParentId !== safeContextProperty('servicePostParentId')) {
|
|
503
|
-
console.log(`Updating servicePostParentId for channel ${channel?.id} to:`, sParentId);
|
|
504
|
-
|
|
505
|
-
safeSend({
|
|
506
|
-
type: Actions.SET_SERVICE_POST_PARENT_ID,
|
|
507
|
-
data: {
|
|
508
|
-
servicePostParentId: sParentId,
|
|
509
|
-
},
|
|
510
|
-
});
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
}, [lastMessage, safeSend, channel?.id, safeContextProperty]);
|
|
280
|
+
}, []);
|
|
514
281
|
|
|
515
|
-
const creatorAndMembersId =
|
|
282
|
+
const creatorAndMembersId = useMemo(() => {
|
|
516
283
|
if (!channel?.members) return null;
|
|
517
284
|
const membersIds: any =
|
|
518
285
|
channel?.members
|
|
@@ -523,7 +290,7 @@ export const ServiceDialogsListItemComponent: React.FC<IDialogListItemProps> = f
|
|
|
523
290
|
return mergedIds?.filter((m: any, pos: any) => mergedIds?.indexOf(m) === pos) ?? [];
|
|
524
291
|
}, [channel, currentUser]);
|
|
525
292
|
|
|
526
|
-
const postParentId =
|
|
293
|
+
const postParentId = useMemo(() => {
|
|
527
294
|
if (!creatorAndMembersId?.length) return null;
|
|
528
295
|
|
|
529
296
|
return creatorAndMembersId?.length && creatorAndMembersId?.includes(currentUser?.id)
|
|
@@ -537,38 +304,17 @@ export const ServiceDialogsListItemComponent: React.FC<IDialogListItemProps> = f
|
|
|
537
304
|
const refreshThreadState = useCallback(() => {
|
|
538
305
|
if (channel?.id && isMountedRef.current) {
|
|
539
306
|
console.log('Forcing thread state refresh for channel:', channel?.id);
|
|
540
|
-
// First ensure we're in a loading state to trigger UI updates
|
|
541
|
-
safeSend({ type: Actions.START_LOADING });
|
|
542
307
|
|
|
543
308
|
// Refetch messages from server
|
|
544
309
|
refetchThreadMessages({
|
|
545
310
|
channelId: channel?.id?.toString(),
|
|
546
311
|
role,
|
|
547
312
|
limit: 2,
|
|
548
|
-
})
|
|
549
|
-
.
|
|
550
|
-
|
|
551
|
-
if (result.data?.threadMessages?.data && isMountedRef.current) {
|
|
552
|
-
console.log(
|
|
553
|
-
`Refreshed ${result.data.threadMessages.data.length} thread messages for channel ${channel?.id}`,
|
|
554
|
-
);
|
|
555
|
-
|
|
556
|
-
safeSend({
|
|
557
|
-
type: Actions.UPDATE_THREAD_MESSAGES,
|
|
558
|
-
data: { threadMessages: result.data.threadMessages.data },
|
|
559
|
-
});
|
|
560
|
-
}
|
|
561
|
-
safeSend({ type: Actions.STOP_LOADING });
|
|
562
|
-
})
|
|
563
|
-
.catch((err) => {
|
|
564
|
-
console.error('Error refreshing thread state:', err);
|
|
565
|
-
safeSend({ type: Actions.STOP_LOADING });
|
|
566
|
-
});
|
|
313
|
+
}).catch((err) => {
|
|
314
|
+
console.error('Error refreshing thread state:', err);
|
|
315
|
+
});
|
|
567
316
|
}
|
|
568
|
-
}, [channel?.id, refetchThreadMessages,
|
|
569
|
-
|
|
570
|
-
// Add a timestamp to track when subscriptions were last set up
|
|
571
|
-
const [subscriptionsTimestamp, setSubscriptionsTimestamp] = useState(Date.now());
|
|
317
|
+
}, [channel?.id, refetchThreadMessages, isMountedRef, role]);
|
|
572
318
|
|
|
573
319
|
// Reset subscriptions when the component gains focus
|
|
574
320
|
useFocusEffect(
|
|
@@ -581,39 +327,17 @@ export const ServiceDialogsListItemComponent: React.FC<IDialogListItemProps> = f
|
|
|
581
327
|
|
|
582
328
|
console.log('ServiceDialogsListItem focused for channel:', channel?.id);
|
|
583
329
|
|
|
584
|
-
// Show loading state
|
|
585
|
-
safeSend({ type: Actions.START_LOADING });
|
|
586
|
-
|
|
587
330
|
// Use a direct refetch with network-only policy to force fresh data
|
|
588
331
|
const fetchFreshData = async () => {
|
|
589
332
|
try {
|
|
590
333
|
// Force a network-only fetch
|
|
591
|
-
|
|
334
|
+
await refetchThreadMessages({
|
|
592
335
|
channelId: channel?.id?.toString(),
|
|
593
336
|
role,
|
|
594
337
|
limit: 2,
|
|
595
338
|
});
|
|
596
|
-
|
|
597
|
-
// Log the refreshed data
|
|
598
|
-
console.log(
|
|
599
|
-
`FOCUS EFFECT: Refetched ${
|
|
600
|
-
result?.data?.threadMessages?.data?.length || 0
|
|
601
|
-
} messages for channel ${channel?.id}`,
|
|
602
|
-
);
|
|
603
|
-
|
|
604
|
-
if (result?.data?.threadMessages?.data && isMountedRef.current) {
|
|
605
|
-
// Update state with fresh data
|
|
606
|
-
safeSend({
|
|
607
|
-
type: Actions.UPDATE_THREAD_MESSAGES,
|
|
608
|
-
data: { threadMessages: result.data.threadMessages.data },
|
|
609
|
-
});
|
|
610
|
-
}
|
|
611
339
|
} catch (error) {
|
|
612
340
|
console.error('Error refetching thread messages on focus:', error);
|
|
613
|
-
} finally {
|
|
614
|
-
if (isMountedRef.current) {
|
|
615
|
-
safeSend({ type: Actions.STOP_LOADING });
|
|
616
|
-
}
|
|
617
341
|
}
|
|
618
342
|
};
|
|
619
343
|
|
|
@@ -623,12 +347,13 @@ export const ServiceDialogsListItemComponent: React.FC<IDialogListItemProps> = f
|
|
|
623
347
|
return () => {
|
|
624
348
|
// Cleanup function when unfocused
|
|
625
349
|
};
|
|
626
|
-
}, [refreshing, channel?.id, refetchThreadMessages,
|
|
350
|
+
}, [refreshing, channel?.id, refetchThreadMessages, role]),
|
|
627
351
|
);
|
|
628
352
|
|
|
629
353
|
return (
|
|
630
354
|
<Pressable
|
|
631
|
-
onPress={() => channel?.id !== selectedChannelId && onOpen(channel?.id, channel?.title, postParentId)}
|
|
355
|
+
// onPress={() => channel?.id !== selectedChannelId && onOpen(channel?.id, channel?.title, postParentId)}
|
|
356
|
+
onPress={() => onOpen(channel?.id, channel?.title, postParentId)}
|
|
632
357
|
className="flex-1 rounded-md border-gray-200 dark:border-gray-600 dark:bg-gray-700"
|
|
633
358
|
style={{ borderBottomWidth: 1, borderColor: '#e5e7eb', marginVertical: 0 }}
|
|
634
359
|
>
|
|
@@ -712,17 +437,6 @@ export const ServiceDialogsListItemComponent: React.FC<IDialogListItemProps> = f
|
|
|
712
437
|
updatedThreads = [...prevThreads, newPostThreadData];
|
|
713
438
|
}
|
|
714
439
|
|
|
715
|
-
// Use the safe state update function
|
|
716
|
-
if (isMountedRef.current) {
|
|
717
|
-
safeSend({
|
|
718
|
-
type: Actions.UPDATE_THREAD_MESSAGES,
|
|
719
|
-
data: {
|
|
720
|
-
threadMessages: updatedThreads,
|
|
721
|
-
directLastMessage: newMessage, // Directly set the new message
|
|
722
|
-
},
|
|
723
|
-
});
|
|
724
|
-
}
|
|
725
|
-
|
|
726
440
|
return {
|
|
727
441
|
...prev,
|
|
728
442
|
threadMessages: {
|
|
@@ -794,17 +508,6 @@ export const ServiceDialogsListItemComponent: React.FC<IDialogListItemProps> = f
|
|
|
794
508
|
console.log(
|
|
795
509
|
`Cannot find thread for chat message in channel ${channel?.id}`,
|
|
796
510
|
);
|
|
797
|
-
|
|
798
|
-
// Even if we can't find the thread, update the UI with the new message
|
|
799
|
-
if (isMountedRef.current) {
|
|
800
|
-
safeSend({
|
|
801
|
-
type: Actions.UPDATE_THREAD_MESSAGES,
|
|
802
|
-
data: {
|
|
803
|
-
directLastMessage: newMessage,
|
|
804
|
-
},
|
|
805
|
-
});
|
|
806
|
-
}
|
|
807
|
-
|
|
808
511
|
return prev;
|
|
809
512
|
}
|
|
810
513
|
|
|
@@ -825,17 +528,6 @@ export const ServiceDialogsListItemComponent: React.FC<IDialogListItemProps> = f
|
|
|
825
528
|
|
|
826
529
|
updatedThreads[threadIndex] = thread;
|
|
827
530
|
|
|
828
|
-
// Use the safe state update function
|
|
829
|
-
if (isMountedRef.current) {
|
|
830
|
-
safeSend({
|
|
831
|
-
type: Actions.UPDATE_THREAD_MESSAGES,
|
|
832
|
-
data: {
|
|
833
|
-
threadMessages: updatedThreads,
|
|
834
|
-
directLastMessage: newMessage,
|
|
835
|
-
},
|
|
836
|
-
});
|
|
837
|
-
}
|
|
838
|
-
|
|
839
531
|
return {
|
|
840
532
|
...prev,
|
|
841
533
|
threadMessages: {
|
|
@@ -65,13 +65,11 @@ export default class Bubble extends React.Component<any> {
|
|
|
65
65
|
|
|
66
66
|
// Add validation for image URL
|
|
67
67
|
if (!image || typeof image !== 'string') {
|
|
68
|
-
console.log('Invalid image URL:', image);
|
|
69
68
|
return null;
|
|
70
69
|
}
|
|
71
70
|
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
// Class components can't use hooks like useMemo
|
|
72
|
+
// Directly render the CachedImage instead
|
|
75
73
|
return (
|
|
76
74
|
<TouchableHighlight
|
|
77
75
|
underlayColor={'transparent'}
|