@messenger-box/platform-mobile 10.0.3-alpha.46 → 10.0.3-alpha.48

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.
@@ -1,27 +1,17 @@
1
1
  import React, { useMemo, useState, useCallback, useRef } from 'react';
2
2
  import {
3
3
  Text,
4
- Image,
5
4
  Pressable,
6
5
  HStack,
7
6
  Box,
8
- AvatarGroup,
9
7
  Avatar,
10
8
  AvatarFallbackText,
11
9
  AvatarImage,
12
- AvatarBadge,
13
- View,
14
10
  } from '@admin-layout/gluestack-ui-mobile';
15
11
  import { format, isToday, isYesterday } from 'date-fns';
16
12
  import { useFocusEffect } from '@react-navigation/native';
17
13
  import { IChannel, IUserAccount } from 'common';
18
- import {
19
- THREAD_CREATED_UPDATED,
20
- CHAT_MESSAGE_ADDED,
21
- useThreadMessagesQuery,
22
- useThreadCreatedUpdatedSubscription,
23
- useThreadChatMessageAddedSubscription,
24
- } from '../../../queries/inboxQueries';
14
+ import { THREAD_CREATED_UPDATED, CHAT_MESSAGE_ADDED, useThreadMessagesQuery } from '../../../queries/inboxQueries';
25
15
  import { startCase } from 'lodash-es';
26
16
  import colors from 'tailwindcss/colors';
27
17
  import { SubscriptionHandler } from './SubscriptionHandler';
@@ -122,136 +112,63 @@ const computeLastMessage = (threadMessages) => {
122
112
  }, allMessages[0]);
123
113
  };
124
114
 
125
- const ServiceChannelWithLastMessage = React.memo(
126
- ({
127
- channel,
128
- lastMessage,
129
- subscribeToNewMessages,
130
- subscribeToChatMessages,
131
- subscribeToMore,
132
- postParentId,
133
- servicePostParentId,
134
- }: {
135
- channel: any;
136
- lastMessage: any;
137
- subscribeToNewMessages: () => void;
138
- subscribeToChatMessages: () => void;
139
- subscribeToMore: any;
140
- postParentId: any;
141
- servicePostParentId: any;
142
- }) => {
143
- React.useEffect(() => {
144
- console.log(`Setting up subscriptions for channel ${channel?.id}`);
145
- // Subscribe and store the unsubscribe functions
146
- let threadUnsubscribe;
147
- let chatUnsubscribe;
148
-
149
- try {
150
- threadUnsubscribe = subscribeToNewMessages();
151
- chatUnsubscribe = subscribeToChatMessages();
152
- } catch (error) {
153
- console.error(`Error setting up subscriptions for channel ${channel?.id}:`, error);
154
- }
155
-
156
- return () => {
157
- // Cleanup subscriptions on unmount
158
- if (threadUnsubscribe && typeof threadUnsubscribe === 'function') {
159
- try {
160
- console.log(`Cleaning up thread subscription for channel ${channel?.id}`);
161
- threadUnsubscribe();
162
- } catch (error) {
163
- console.error(`Error cleaning up thread subscription for channel ${channel?.id}:`, error);
164
- }
165
- }
115
+ const ServiceChannelWithLastMessage = React.memo(({ channel, lastMessage }: { channel: any; lastMessage: any }) => {
116
+ // Debug output for component rendering
117
+ React.useEffect(() => {
118
+ console.log(`ServiceChannelWithLastMessage rendered for channel ${channel?.id}:`, {
119
+ hasLastMessage: !!lastMessage,
120
+ messageId: lastMessage?.id,
121
+ messageText: lastMessage?.message?.substring(0, 20) + (lastMessage?.message?.length > 20 ? '...' : ''),
122
+ date: lastMessage?.createdAt ? safeDate(lastMessage.createdAt)?.toISOString() : 'none',
123
+ });
124
+ }, [lastMessage, channel?.id]);
166
125
 
167
- if (chatUnsubscribe && typeof chatUnsubscribe === 'function') {
168
- try {
169
- console.log(`Cleaning up chat subscription for channel ${channel?.id}`);
170
- chatUnsubscribe();
171
- } catch (error) {
172
- console.error(`Error cleaning up chat subscription for channel ${channel?.id}:`, error);
173
- }
174
- }
175
- };
176
- }, [subscribeToNewMessages, subscribeToChatMessages, channel?.id]);
177
-
178
- // Debug output for component rendering
179
- React.useEffect(() => {
180
- console.log(`ServiceChannelWithLastMessage rendered for channel ${channel?.id}:`, {
181
- hasLastMessage: !!lastMessage,
182
- messageId: lastMessage?.id,
183
- messageText: lastMessage?.message?.substring(0, 20) + (lastMessage?.message?.length > 20 ? '...' : ''),
184
- date: lastMessage?.createdAt ? safeDate(lastMessage.createdAt)?.toISOString() : 'none',
185
- });
186
- }, [lastMessage, channel?.id]);
187
-
188
- const count = 30;
189
- const title = channel?.title.slice(0, count) + (channel?.title.length > count ? '...' : '');
190
-
191
- // Define message display text
192
- let displayMessage = 'No messages yet';
193
-
194
- if (lastMessage) {
195
- // Check for file attachments
196
- const hasFileAttachments = lastMessage.files?.data?.length > 0;
197
-
198
- // Check if the message appears to be an image
199
- const isImageMessage =
200
- lastMessage.message?.includes('<img') ||
201
- lastMessage.message?.includes('[Image]') ||
202
- lastMessage.message?.includes('![') ||
203
- (/\.(jpeg|jpg|gif|png|bmp|webp)/i.test(lastMessage.message || '') &&
204
- ((lastMessage.message || '').includes('http') || (lastMessage.message || '').includes('/images/')));
205
-
206
- if (hasFileAttachments) {
207
- displayMessage = '📎 File attachment';
208
- } else if (isImageMessage) {
209
- displayMessage = '[Image]';
210
- } else if (lastMessage.message && lastMessage.message.trim() !== '') {
211
- displayMessage = lastMessage.message;
212
- } else {
213
- displayMessage = '(Empty message)';
214
- }
126
+ const count = 30;
127
+ const title = channel?.title.slice(0, count) + (channel?.title.length > count ? '...' : '');
128
+
129
+ // Define message display text
130
+ let displayMessage = 'No messages yet';
131
+
132
+ if (lastMessage) {
133
+ // Check for file attachments
134
+ const hasFileAttachments = lastMessage.files?.data?.length > 0;
135
+
136
+ // Check if the message appears to be an image
137
+ const isImageMessage =
138
+ lastMessage.message?.includes('<img') ||
139
+ lastMessage.message?.includes('[Image]') ||
140
+ lastMessage.message?.includes('![') ||
141
+ (/\.(jpeg|jpg|gif|png|bmp|webp)/i.test(lastMessage.message || '') &&
142
+ ((lastMessage.message || '').includes('http') || (lastMessage.message || '').includes('/images/')));
143
+
144
+ if (hasFileAttachments) {
145
+ displayMessage = '📎 File attachment';
146
+ } else if (isImageMessage) {
147
+ displayMessage = '[Image]';
148
+ } else if (lastMessage.message && lastMessage.message.trim() !== '') {
149
+ displayMessage = lastMessage.message;
150
+ } else {
151
+ displayMessage = '(Empty message)';
215
152
  }
153
+ }
216
154
 
217
- return (
218
- <>
219
- <SubscriptionHandler
220
- subscribeToMore={subscribeToMore}
221
- document={THREAD_CREATED_UPDATED}
222
- variables={{
223
- channelId: channel?.id?.toString(),
224
- postParentId: postParentId || servicePostParentId || null,
225
- }}
226
- updateQuery={undefined} // Provide custom updateQuery if needed
227
- />
228
- <SubscriptionHandler
229
- subscribeToMore={subscribeToMore}
230
- document={CHAT_MESSAGE_ADDED}
231
- variables={{
232
- channelId: channel?.id?.toString(),
233
- postParentId: postParentId || servicePostParentId || null,
234
- }}
235
- updateQuery={undefined} // Provide custom updateQuery if needed
236
- />
237
- <HStack space={'sm'} className="flex-1 justify-between">
238
- <Box className="flex-[0.8]">
239
- <Text color={colors.gray[600]} className="text-base text-wrap flex-wrap font-semibold">
240
- {title}
241
- </Text>
242
- <Text color={colors.gray[600]} numberOfLines={1}>
243
- {displayMessage}
244
- </Text>
245
- </Box>
246
-
247
- <Box className="flex-[0.2]">
248
- <Text color={colors.gray[500]}>{lastMessage ? createdAtText(lastMessage?.createdAt) : ''}</Text>
249
- </Box>
250
- </HStack>
251
- </>
252
- );
253
- },
254
- );
155
+ return (
156
+ <HStack space={'sm'} className="flex-1 justify-between">
157
+ <Box className="flex-[0.8]">
158
+ <Text color={colors.gray[600]} className="text-base text-wrap flex-wrap font-semibold">
159
+ {title}
160
+ </Text>
161
+ <Text color={colors.gray[600]} numberOfLines={1}>
162
+ {displayMessage}
163
+ </Text>
164
+ </Box>
165
+
166
+ <Box className="flex-[0.2]">
167
+ <Text color={colors.gray[500]}>{lastMessage ? createdAtText(lastMessage?.createdAt) : ''}</Text>
168
+ </Box>
169
+ </HStack>
170
+ );
171
+ });
255
172
 
256
173
  /**
257
174
  * TODO:
@@ -403,133 +320,123 @@ export const ServiceDialogsListItemComponent: React.FC<IDialogListItemProps> = f
403
320
  key={`channel-${channel?.id}-${subscriptionsTimestamp}`}
404
321
  channel={channel}
405
322
  lastMessage={lastMessage}
406
- subscribeToNewMessages={() =>
407
- shouldQuery
408
- ? subscribeToMore({
409
- document: THREAD_CREATED_UPDATED,
410
- variables: {
411
- channelId: channel?.id?.toString(),
412
- postParentId: postParentId || servicePostParentId || null,
413
- },
414
- updateQuery: (prev, { subscriptionData }: any) => {
415
- if (!subscriptionData?.data) {
416
- return prev;
417
- }
418
- try {
419
- const newPostThreadData: any =
420
- subscriptionData?.data?.threadCreatedUpdated?.data;
421
- const newMessage: any =
422
- subscriptionData?.data?.threadCreatedUpdated?.lastMessage;
423
- if (!newPostThreadData || !newMessage) {
424
- return prev;
425
- }
426
- const prevThreads = prev?.threadMessages?.data || [];
427
- const threadExists = prevThreads.some(
428
- (t: any) => t.id === newPostThreadData?.id,
429
- );
430
- let updatedThreads;
431
- if (threadExists) {
432
- updatedThreads = prevThreads.map((t: any) =>
433
- t.id === newPostThreadData?.id
434
- ? {
435
- ...t,
436
- replies: [...(t?.replies || []), newMessage],
437
- replyCount: newPostThreadData?.replyCount,
438
- lastReplyAt: newPostThreadData?.lastReplyAt,
439
- updatedAt: newPostThreadData?.updatedAt,
440
- }
441
- : t,
442
- );
443
- } else {
444
- updatedThreads = [...prevThreads, newPostThreadData];
445
- }
446
- return {
447
- ...prev,
448
- threadMessages: {
449
- ...prev?.threadMessages,
450
- totalCount:
451
- newPostThreadData?.totalCount ??
452
- prev?.threadMessages?.totalCount ??
453
- 0,
454
- data: updatedThreads,
455
- },
456
- };
457
- } catch (error) {
458
- return prev;
459
- }
460
- },
461
- onError: (error) => {
462
- console.error(`Thread subscription error for channel ${channel?.id}:`, error);
463
- },
464
- })
465
- : undefined
466
- }
467
- subscribeToChatMessages={() =>
468
- shouldQuery
469
- ? subscribeToMore({
470
- document: CHAT_MESSAGE_ADDED,
471
- variables: {
472
- channelId: channel?.id?.toString(),
473
- postParentId: postParentId || servicePostParentId || null,
474
- },
475
- updateQuery: (prev, { subscriptionData }: any) => {
476
- if (!subscriptionData?.data) {
477
- return prev;
478
- }
479
- try {
480
- const newMessage = subscriptionData?.data?.chatMessageAdded;
481
- if (!newMessage) {
482
- return prev;
483
- }
484
- const prevThreads = prev?.threadMessages?.data || [];
485
- const threadIndex = prevThreads.findIndex((t: any) => {
486
- if (newMessage.parentId && t.post?.id === newMessage.parentId) {
487
- return true;
488
- }
489
- if (
490
- t.replies &&
491
- t.replies.some((r: any) => r.id === newMessage.parentId)
492
- ) {
493
- return true;
494
- }
495
- return false;
496
- });
497
- if (threadIndex === -1) {
498
- return prev;
499
- }
500
- const updatedThreads = [...prevThreads];
501
- const thread = { ...updatedThreads[threadIndex] };
502
- thread.replies = [...(thread.replies || []), newMessage];
503
- const currentReplyCount =
504
- typeof thread.replyCount === 'number' ? thread.replyCount : 0;
505
- thread.replyCount = currentReplyCount + 1;
506
- thread.lastReplyAt = newMessage.createdAt;
507
- thread.updatedAt = newMessage.createdAt;
508
- updatedThreads[threadIndex] = thread;
509
- return {
510
- ...prev,
511
- threadMessages: {
512
- ...prev?.threadMessages,
513
- data: updatedThreads,
514
- },
515
- };
516
- } catch (error) {
517
- return prev;
518
- }
519
- },
520
- onError: (error) => {
521
- console.error(
522
- `Chat message subscription error for channel ${channel?.id}:`,
523
- error,
524
- );
525
- },
526
- })
527
- : undefined
528
- }
529
- subscribeToMore={subscribeToMore}
530
- postParentId={postParentId}
531
- servicePostParentId={servicePostParentId}
532
323
  />
324
+
325
+ {/* Subscription handlers for real-time updates */}
326
+ {shouldQuery && (
327
+ <>
328
+ <SubscriptionHandler
329
+ subscribeToMore={subscribeToMore}
330
+ document={THREAD_CREATED_UPDATED}
331
+ variables={{
332
+ channelId: channel?.id?.toString(),
333
+ postParentId: postParentId || servicePostParentId || null,
334
+ }}
335
+ updateQuery={(prev, { subscriptionData }: any) => {
336
+ if (!subscriptionData?.data) {
337
+ return prev;
338
+ }
339
+ try {
340
+ const newPostThreadData: any =
341
+ subscriptionData?.data?.threadCreatedUpdated?.data;
342
+ const newMessage: any =
343
+ subscriptionData?.data?.threadCreatedUpdated?.lastMessage;
344
+ if (!newPostThreadData || !newMessage) {
345
+ return prev;
346
+ }
347
+ const prevThreads = prev?.threadMessages?.data || [];
348
+ const threadExists = prevThreads.some(
349
+ (t: any) => t.id === newPostThreadData?.id,
350
+ );
351
+ let updatedThreads;
352
+ if (threadExists) {
353
+ updatedThreads = prevThreads.map((t: any) =>
354
+ t.id === newPostThreadData?.id
355
+ ? {
356
+ ...t,
357
+ replies: [...(t?.replies || []), newMessage],
358
+ replyCount: newPostThreadData?.replyCount,
359
+ lastReplyAt: newPostThreadData?.lastReplyAt,
360
+ updatedAt: newPostThreadData?.updatedAt,
361
+ }
362
+ : t,
363
+ );
364
+ } else {
365
+ updatedThreads = [...prevThreads, newPostThreadData];
366
+ }
367
+ return {
368
+ ...prev,
369
+ threadMessages: {
370
+ ...prev?.threadMessages,
371
+ totalCount:
372
+ newPostThreadData?.totalCount ??
373
+ prev?.threadMessages?.totalCount ??
374
+ 0,
375
+ data: updatedThreads,
376
+ },
377
+ };
378
+ } catch (error) {
379
+ console.error(`Thread subscription error for channel ${channel?.id}:`, error);
380
+ return prev;
381
+ }
382
+ }}
383
+ />
384
+ <SubscriptionHandler
385
+ subscribeToMore={subscribeToMore}
386
+ document={CHAT_MESSAGE_ADDED}
387
+ variables={{
388
+ channelId: channel?.id?.toString(),
389
+ postParentId: postParentId || servicePostParentId || null,
390
+ }}
391
+ updateQuery={(prev, { subscriptionData }: any) => {
392
+ if (!subscriptionData?.data) {
393
+ return prev;
394
+ }
395
+ try {
396
+ const newMessage = subscriptionData?.data?.chatMessageAdded;
397
+ if (!newMessage) {
398
+ return prev;
399
+ }
400
+ const prevThreads = prev?.threadMessages?.data || [];
401
+ const threadIndex = prevThreads.findIndex((t: any) => {
402
+ if (newMessage.parentId && t.post?.id === newMessage.parentId) {
403
+ return true;
404
+ }
405
+ if (t.replies && t.replies.some((r: any) => r.id === newMessage.parentId)) {
406
+ return true;
407
+ }
408
+ return false;
409
+ });
410
+ if (threadIndex === -1) {
411
+ return prev;
412
+ }
413
+ const updatedThreads = [...prevThreads];
414
+ const thread = { ...updatedThreads[threadIndex] };
415
+ thread.replies = [...(thread.replies || []), newMessage];
416
+ const currentReplyCount =
417
+ typeof thread.replyCount === 'number' ? thread.replyCount : 0;
418
+ thread.replyCount = currentReplyCount + 1;
419
+ thread.lastReplyAt = newMessage.createdAt;
420
+ thread.updatedAt = newMessage.createdAt;
421
+ updatedThreads[threadIndex] = thread;
422
+ return {
423
+ ...prev,
424
+ threadMessages: {
425
+ ...prev?.threadMessages,
426
+ data: updatedThreads,
427
+ },
428
+ };
429
+ } catch (error) {
430
+ console.error(
431
+ `Chat message subscription error for channel ${channel?.id}:`,
432
+ error,
433
+ );
434
+ return prev;
435
+ }
436
+ }}
437
+ />
438
+ </>
439
+ )}
533
440
  </Box>
534
441
  </HStack>
535
442
  </Pressable>
@@ -10,6 +10,6 @@ export const config = cleanEnv(process['APP_ENV'] || process.env, {
10
10
  THREADS_PATH: str({ default: 'MainStack.Thread' }),
11
11
  CALL_TO_ACTION_PATH: str({ default: 'MainStack.GuestReservationRequestDetail' }),
12
12
  CALL_TO_ACTION_BOX_BGCOLOR: str({ default: '#0084ff' }),
13
- CALL_TO_ACTION_BUTTON_BORDERCOLOR: str({ default: '#fff' }),
14
- CALL_TO_ACTION_TEXT_COLOR: str({ default: '#fff' }),
13
+ CALL_TO_ACTION_BUTTON_BORDERCOLOR: str({ default: '#000' }),
14
+ CALL_TO_ACTION_TEXT_COLOR: str({ default: '#000' }),
15
15
  });
@@ -371,7 +371,12 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
371
371
  // Required fields that Apollo expects in the cache
372
372
  propsConfiguration: {
373
373
  __typename: 'MachineConfiguration' as const,
374
+ id: null,
374
375
  resource: '' as any,
376
+ contents: null,
377
+ keys: null,
378
+ target: null,
379
+ overrides: null,
375
380
  },
376
381
  props: {},
377
382
  files: {
@@ -659,7 +664,12 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
659
664
  // Required fields that Apollo expects in the cache
660
665
  propsConfiguration: {
661
666
  __typename: 'MachineConfiguration' as const,
667
+ id: null,
662
668
  resource: '' as any,
669
+ contents: null,
670
+ keys: null,
671
+ target: null,
672
+ overrides: null,
663
673
  },
664
674
  props: {},
665
675
  files: {
@@ -937,7 +947,12 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
937
947
  // Required fields that Apollo expects in the cache
938
948
  propsConfiguration: {
939
949
  __typename: 'MachineConfiguration' as const,
950
+ id: null,
940
951
  resource: '' as any,
952
+ contents: null,
953
+ keys: null,
954
+ target: null,
955
+ overrides: null,
941
956
  },
942
957
  props: {},
943
958
  files: {
@@ -1362,22 +1377,25 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
1362
1377
  <>
1363
1378
  {attachment?.callToAction && action ? (
1364
1379
  <Box className={`bg-[${CALL_TO_ACTION_BOX_BGCOLOR}] rounded-[15] pb-2`}>
1380
+ <MessageText
1381
+ {...props}
1382
+ containerStyle={{
1383
+ left: { paddingLeft: 0, marginLeft: 0 },
1384
+ }}
1385
+ textStyle={{
1386
+ left: { marginLeft: 0 },
1387
+ }}
1388
+ />
1365
1389
  <Button
1366
1390
  variant={'outline'}
1367
1391
  size={'sm'}
1368
- className={`border-[${CALL_TO_ACTION_BUTTON_BORDERCOLOR}] mt-2 rounded-full `}
1392
+ className={`border-[${CALL_TO_ACTION_BUTTON_BORDERCOLOR}] my-2 rounded-full `}
1369
1393
  onPress={() => action && params && navigation.navigate(action, params)}
1370
1394
  >
1371
1395
  <ButtonText className={`color-[${CALL_TO_ACTION_TEXT_COLOR}]`}>
1372
1396
  {attachment.callToAction.title}
1373
1397
  </ButtonText>
1374
1398
  </Button>
1375
- <MessageText
1376
- {...props}
1377
- textStyle={{
1378
- left: { marginLeft: 5, color: CALL_TO_ACTION_TEXT_COLOR, paddingHorizontal: 2 },
1379
- }}
1380
- />
1381
1399
  </Box>
1382
1400
  ) : (
1383
1401
  <TouchableHighlight