@messenger-box/platform-mobile 0.0.1-alpha.362 → 0.0.1-alpha.365

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 (29) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/lib/index.js +2281 -553
  3. package/lib/index.js.map +1 -1
  4. package/lib/screens/inbox/DialogThreadMessages.d.ts +7 -0
  5. package/lib/screens/inbox/DialogThreads.d.ts +6 -0
  6. package/lib/screens/inbox/components/SupportServiceDialogsListItem.d.ts +21 -0
  7. package/lib/screens/inbox/components/ThreadsViewItem.d.ts +18 -0
  8. package/lib/screens/inbox/config/config.d.ts +2 -0
  9. package/lib/screens/inbox/containers/Dialogs.d.ts +1 -0
  10. package/lib/screens/inbox/containers/SupportServiceDialogs.d.ts +6 -0
  11. package/lib/screens/inbox/containers/ThreadConversationView.d.ts +11 -0
  12. package/lib/screens/inbox/containers/ThreadsView.d.ts +8 -0
  13. package/lib/screens/index.d.ts +2 -0
  14. package/package.json +4 -4
  15. package/src/navigation/InboxNavigation.tsx +63 -0
  16. package/src/screens/inbox/DialogThreadMessages.tsx +90 -0
  17. package/src/screens/inbox/DialogThreads.tsx +107 -0
  18. package/src/screens/inbox/Inbox.tsx +5 -3
  19. package/src/screens/inbox/components/DialogsListItem.tsx +7 -3
  20. package/src/screens/inbox/components/SlackMessageContainer/SlackBubble.tsx +5 -5
  21. package/src/screens/inbox/components/SupportServiceDialogsListItem.tsx +295 -0
  22. package/src/screens/inbox/components/ThreadsViewItem.tsx +236 -0
  23. package/src/screens/inbox/config/config.ts +4 -0
  24. package/src/screens/inbox/containers/ConversationView.tsx +440 -156
  25. package/src/screens/inbox/containers/Dialogs.tsx +2 -1
  26. package/src/screens/inbox/containers/SupportServiceDialogs.tsx +119 -0
  27. package/src/screens/inbox/containers/ThreadConversationView.tsx +764 -0
  28. package/src/screens/inbox/containers/ThreadsView.tsx +205 -0
  29. package/src/screens/index.ts +3 -1
@@ -1,9 +1,21 @@
1
1
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
- import { Box, Button, HStack, Icon, Image, Spinner, Text, useColorModeValue, ScrollView } from 'native-base';
3
- import { Platform, TouchableOpacity } from 'react-native';
4
- import { useNavigation, useFocusEffect } from '@react-navigation/native';
2
+ import {
3
+ Box,
4
+ Button,
5
+ HStack,
6
+ Icon,
7
+ Image,
8
+ Spinner,
9
+ Text,
10
+ useColorModeValue,
11
+ Avatar,
12
+ ScrollView,
13
+ Center,
14
+ } from 'native-base';
15
+ import { Platform, TouchableOpacity, TouchableHighlight } from 'react-native';
16
+ import { useNavigation, useFocusEffect, useIsFocused } from '@react-navigation/native';
5
17
  import { useSelector } from 'react-redux';
6
- import { orderBy, uniqBy } from 'lodash';
18
+ import { orderBy, uniqBy, startCase } from 'lodash';
7
19
  import * as ImagePicker from 'expo-image-picker';
8
20
  import { encode as atob } from 'base-64';
9
21
  import { Ionicons, MaterialCommunityIcons } from '@expo/vector-icons';
@@ -15,12 +27,15 @@ import {
15
27
  useSendMessagesMutation,
16
28
  useViewChannelDetailQuery,
17
29
  useUploadFilesNative,
30
+ useGetNewMongooseObjectIdQuery,
31
+ useOnChatMessageAddedSubscription,
18
32
  } from '@messenger-box/platform-client';
19
33
  import { IFileInfo } from '@messenger-box/core';
20
34
  import { config } from '../config';
21
35
  import { userSelector } from '@adminide-stack/user-auth0-client';
22
36
  import { SlackMessage, ImageViewerModal } from '../components/SlackMessageContainer';
23
37
  import CachedImage from '../components/CachedImage';
38
+ import { format, isToday, isYesterday } from 'date-fns';
24
39
  const {
25
40
  MESSAGES_PER_PAGE,
26
41
  CALL_TO_ACTION_BOX_BGCOLOR,
@@ -29,9 +44,18 @@ const {
29
44
  CALL_TO_ACTION_TEXT_COLOR,
30
45
  } = config;
31
46
 
47
+ const createdAtText = (value: string) => {
48
+ if (!value) return '';
49
+ let date = new Date(value);
50
+ if (isToday(date)) return 'Today';
51
+ if (isYesterday(date)) return 'Yesterday';
52
+ return format(new Date(value), 'MMM dd, yyyy');
53
+ };
54
+
32
55
  interface IMessageProps extends IMessage {
33
56
  type: string;
34
57
  propsConfiguration?: any;
58
+ replies?: any;
35
59
  }
36
60
 
37
61
  export interface AlertMessageAttachmentsInterface {
@@ -58,10 +82,26 @@ const ConversationViewComponent = ({ channelId }: any) => {
58
82
  const [images, setImages] = useState<ImagePicker.ImageInfo[]>([]);
59
83
  const [msg, setMsg] = useState<string>('');
60
84
  const [loading, setLoading] = useState(false);
85
+ const [loadEarlierMsg, setLoadEarlierMsg] = useState(false);
61
86
  const [imageLoading, setImageLoading] = useState(false);
62
87
  const [expoTokens, setExpoTokens] = useState<any[]>([]);
63
88
  const [isShowImageViewer, setImageViewer] = useState<boolean>(false);
64
89
  const [imageObject, setImageObject] = useState<any>({});
90
+ const isFocused = useIsFocused();
91
+ const { data: mongooseObjectId } = useGetNewMongooseObjectIdQuery({
92
+ fetchPolicy: 'network-only',
93
+ pollInterval: 5000,
94
+ });
95
+
96
+ const {
97
+ data: newMessage,
98
+ loading: newMsgLoading,
99
+ error: newMsgError,
100
+ }: any = useOnChatMessageAddedSubscription({
101
+ variables: {
102
+ channelId: channelId?.toString(),
103
+ },
104
+ });
65
105
 
66
106
  const { startUpload } = useUploadFilesNative();
67
107
 
@@ -74,10 +114,12 @@ const ConversationViewComponent = ({ channelId }: any) => {
74
114
  }: any = useMessagesQuery({
75
115
  variables: {
76
116
  channelId: channelId?.toString(),
117
+ parentId: null,
77
118
  limit: MESSAGES_PER_PAGE,
78
119
  },
79
120
  skip: !channelId,
80
121
  fetchPolicy: 'cache-and-network',
122
+ nextFetchPolicy: 'cache-first',
81
123
  });
82
124
 
83
125
  const {
@@ -91,14 +133,14 @@ const ConversationViewComponent = ({ channelId }: any) => {
91
133
  });
92
134
  // const { data: users } = useGetAllUsersQuery();
93
135
 
94
- const { data: checkForMessages }: any = useCheckForNewMessagesQuery({
95
- variables: {
96
- channelId: channelId?.toString(),
97
- },
98
- skip: !channelId,
99
- fetchPolicy: 'network-only',
100
- pollInterval: 5000,
101
- });
136
+ // const { data: checkForMessages }: any = useCheckForNewMessagesQuery({
137
+ // variables: {
138
+ // channelId: channelId?.toString(),
139
+ // },
140
+ // skip: !channelId,
141
+ // fetchPolicy: 'network-only',
142
+ // pollInterval: 5000,
143
+ // });
102
144
 
103
145
  useFocusEffect(
104
146
  React.useCallback(() => {
@@ -106,6 +148,7 @@ const ConversationViewComponent = ({ channelId }: any) => {
106
148
  refetchChannelDetail({ id: channelId?.toString() });
107
149
  refetch({
108
150
  channelId: channelId?.toString(),
151
+ parentId: null,
109
152
  limit: MESSAGES_PER_PAGE,
110
153
  }).then(({ data }) => {
111
154
  if (!data?.messages) {
@@ -121,7 +164,7 @@ const ConversationViewComponent = ({ channelId }: any) => {
121
164
  setTotalCount(0);
122
165
  setChannelMessages([]);
123
166
  };
124
- }, []),
167
+ }, [isFocused]),
125
168
  );
126
169
 
127
170
  React.useEffect(() => {
@@ -159,17 +202,52 @@ const ConversationViewComponent = ({ channelId }: any) => {
159
202
  // // if (totalCount !== messeageTotalCount) setTotalCount(messeageTotalCount);
160
203
  // }
161
204
  // }, [data, loadingOldMessages, channelMessages]);///
205
+ ////......... initiate messages ......................////
206
+ // useEffect(() => {
207
+ // if (data?.messages?.data && (loadingOldMessages || channelMessages.length === 0)) {
208
+ // console.log('loading msg')
209
+ // const { data: messages, totalCount: messeageTotalCount } = data.messages;
210
+ // if (messages && messages.length > 0) {
211
+ // setChannelMessages((oldMessages: any) => uniqBy([...messages, ...oldMessages], ({ id }) => id));
212
+ // setLoadingOldMessages(false);
213
+ // }
214
+ // if (totalCount !== messeageTotalCount) setTotalCount(messeageTotalCount);
215
+ // }
216
+ // }, [data, loadingOldMessages, channelMessages, totalCount]);
217
+ ////.... initiate messages end................................////
218
+
219
+ // useEffect(() => {
220
+ // if (data?.messages?.data && (loadingOldMessages || channelMessages.length === 0)) {
221
+ // console.log('initiate msg')
222
+ // const { data: messages, totalCount: messeageTotalCount } = data.messages;
223
+ // if (messages && messages.length > 0) {
224
+ // setChannelMessages((oldMessages: any) => uniqBy([...messages, ...oldMessages], ({ id }) => id));
225
+ // setTotalCount(messeageTotalCount);
226
+ // }
227
+ // if(loadingOldMessages) setLoadingOldMessages(false);
228
+ // }
229
+
230
+ // }, [data, channelMessages,loadingOldMessages]);
162
231
 
163
232
  useEffect(() => {
164
- if (data?.messages?.data && (loadingOldMessages || channelMessages.length === 0)) {
233
+ if ((data?.messages?.data && channelMessages.length === 0) || (data?.messages?.data && loadingOldMessages)) {
165
234
  const { data: messages, totalCount: messeageTotalCount } = data.messages;
166
235
  if (messages && messages.length > 0) {
167
236
  setChannelMessages((oldMessages: any) => uniqBy([...messages, ...oldMessages], ({ id }) => id));
168
- setLoadingOldMessages(false);
237
+ setTotalCount(messeageTotalCount);
169
238
  }
170
- if (totalCount !== messeageTotalCount) setTotalCount(messeageTotalCount);
239
+ setLoadEarlierMsg(false);
240
+ if (loadingOldMessages) setLoadingOldMessages(false);
241
+ }
242
+ }, [data, loadingOldMessages, channelMessages]);
243
+
244
+ React.useEffect(() => {
245
+ if (newMessage) {
246
+ const msg = newMessage?.chatMessageAdded;
247
+ setTotalCount((preCount: any) => preCount + 1);
248
+ setChannelMessages((oldMessages: any) => uniqBy([...oldMessages, msg], ({ id }) => id));
171
249
  }
172
- }, [data, loadingOldMessages, channelMessages, totalCount]);
250
+ }, [newMessage]);
173
251
 
174
252
  // useEffect(() => {
175
253
  // if (data?.messages?.data) {
@@ -198,27 +276,30 @@ const ConversationViewComponent = ({ channelId }: any) => {
198
276
  // });
199
277
  // }
200
278
  // }, [checkForMessages, totalCount]);
201
-
202
- useEffect(() => {
203
- if (
204
- !messageLoading &&
205
- checkForMessages?.messages?.totalCount &&
206
- checkForMessages?.messages?.totalCount > totalCount
207
- ) {
208
- const numberOfNewMessages = checkForMessages?.messages?.totalCount - totalCount;
209
- console.log('new msg check');
210
- refetch({
211
- limit: numberOfNewMessages,
212
- }).then(({ data }) => {
213
- if (!data?.messages) {
214
- return;
215
- }
216
- const { data: messages, totalCount }: any = data.messages;
217
- setTotalCount(totalCount);
218
- setChannelMessages((oldMessages: any) => uniqBy([...oldMessages, ...messages], ({ id }) => id));
219
- });
220
- }
221
- }, [checkForMessages, totalCount]);
279
+ ////////...............New msg check...........////
280
+ // useEffect(() => {
281
+ // if (
282
+ // !messageLoading &&
283
+ // checkForMessages?.messages?.totalCount &&
284
+ // checkForMessages?.messages?.totalCount > totalCount
285
+ // ) {
286
+ // const numberOfNewMessages = checkForMessages?.messages?.totalCount - totalCount;
287
+ // console.log('new msg check');
288
+ // refetch({
289
+ // channelId: channelId?.toString(),
290
+ // parentId: null,
291
+ // limit: numberOfNewMessages,
292
+ // }).then(({ data }) => {
293
+ // if (!data?.messages) {
294
+ // return;
295
+ // }
296
+ // const { data: messages, totalCount }: any = data.messages;
297
+ // setTotalCount(totalCount);
298
+ // setChannelMessages((oldMessages: any) => uniqBy([...oldMessages, ...messages], ({ id }) => id));
299
+ // });
300
+ // }
301
+ // }, [checkForMessages, totalCount]);
302
+ ////////////....new msg check end.........//
222
303
 
223
304
  // const onFetchOld = useCallback(() => {
224
305
  // // if (data?.messages?.totalCount > channelMessages.length) {
@@ -238,12 +319,25 @@ const ConversationViewComponent = ({ channelId }: any) => {
238
319
  // }
239
320
  // };
240
321
 
241
- const onFetchOld = useCallback(() => {
322
+ // const onFetchOld = useCallback(() => {
323
+ // if (data?.messages?.totalCount > channelMessages.length) {
324
+ // console.log('fetchmore')
325
+
326
+ // refetch({ channelId: channelId?.toString(), parentId: null, skip: channelMessages.length })?.then((res:any)=>{
327
+ // setLoadingOldMessages(true);
328
+ // });
329
+
330
+ // }
331
+ // }, [data, channelMessages]);
332
+
333
+ const onFetchOld = useCallback((data: any, channelMessages: any) => {
242
334
  if (data?.messages?.totalCount > channelMessages.length) {
243
- setLoadingOldMessages(true);
244
- refetch({ skip: channelMessages.length });
335
+ setLoadEarlierMsg(true);
336
+ refetch({ channelId: channelId?.toString(), parentId: null, skip: channelMessages.length })?.then(
337
+ (res: any) => setLoadingOldMessages(true),
338
+ );
245
339
  }
246
- }, [data, channelMessages]);
340
+ }, []);
247
341
 
248
342
  // const onFetchOld = () => {
249
343
  // if(totalCount > channelMessages.length){
@@ -420,102 +514,223 @@ const ConversationViewComponent = ({ channelId }: any) => {
420
514
  // [setChannelMessages, currentUser, channelId, images,expoTokens],
421
515
  // );
422
516
 
423
- const handleSend = async (message: string) => {
424
- if (!channelId) return;
425
- if (!message && message != ' ' && images.length == 0) return;
426
-
427
- setLoading(true);
428
- const { data } = await sendMsg({
429
- variables: {
430
- channelId,
431
- content: message,
432
- },
433
- update: (cache, { data, errors }: any) => {
434
- if (!data || errors) {
435
- setLoading(false);
436
- return;
437
- }
438
- setChannelMessages((messages: any) => [...messages, data?.sendMessage]);
439
- setTotalCount((t: any) => t + 1);
440
- setChannelToTop(channelToTop + 1);
441
- setLoading(false);
442
- setMsg('');
443
- const givenName = auth?.profile?.given_name ?? '';
444
- const familyName = auth?.profile?.family_name ?? '';
445
- const fullName = givenName ? givenName + ' ' + familyName : '';
446
- const title: String = fullName ? fullName : 'Message';
447
- const body: String = message;
448
- const notificationData: any = {
449
- url: config.INBOX_MESSEGE_PATH,
450
- params: { channelId, hideTabBar: true },
451
- screen: 'DialogMessages',
452
- };
453
- refetchChannelDetail({ id: channelId?.toString() })?.then((res: any) => {
454
- if (res?.data?.viewChannelDetail?.members?.length) {
455
- const channelData: any =
456
- res?.data?.viewChannelDetail?.members?.filter((mu: any) => mu?.user?.id != auth?.id) ?? [];
457
- const tokens: any =
458
- channelData
459
- ?.map(
460
- (u: any) =>
461
- u?.user?.tokens
462
- ?.filter((t: any) => t?.type == 'EXPO_NOTIFICATION_TOKEN')
463
- ?.map((et: any) => et?.token) ?? [],
464
- )
465
- ?.flat(1)
466
- ?.filter((t: any) => t)
467
- ?.filter((value: any, index: any, array: any) => array.indexOf(value) === index) ?? [];
468
- console.log('expo to', JSON.stringify(tokens));
469
- if (tokens?.length > 0) {
470
- const to: any = tokens?.length > 0 ? tokens : [];
471
-
472
- sendPushNotification(title, body, notificationData, to);
473
- }
474
- }
517
+ const handleSend = useCallback(
518
+ async (message: string) => {
519
+ if (!channelId) return;
520
+ if (!message && message != ' ' && images.length == 0) return;
521
+
522
+ if (images && images.length > 0) {
523
+ const postId: any = mongooseObjectId?.getNewMongooseObjectId;
524
+ setLoading(true);
525
+ const uploadResponse = await startUpload({
526
+ file: images,
527
+ saveUploadedFile: {
528
+ variables: {
529
+ postId,
530
+ },
531
+ },
532
+ createUploadLink: {
533
+ variables: {
534
+ postId,
535
+ },
536
+ },
475
537
  });
476
- },
477
- });
478
- if (images && images.length > 0 && data?.sendMessage?.id) {
479
- const { id: postId } = data.sendMessage;
480
- setLoading(true);
481
- const uploadResponse = await startUpload({
482
- file: images,
483
- saveUploadedFile: {
538
+ if (uploadResponse?.error) setLoading(false);
539
+ const uploadedFiles = uploadResponse.data as unknown as IFileInfo[];
540
+
541
+ if (uploadResponse.data) {
542
+ setImage('');
543
+ setFiles([]);
544
+ setImages([]);
545
+ //setLoading(false);
546
+ const files = uploadedFiles?.map((f: any) => f.id) ?? null;
547
+ await sendMsg({
548
+ variables: {
549
+ postId,
550
+ channelId,
551
+ content: message,
552
+ files,
553
+ },
554
+ update: (cache, { data, errors }: any) => {
555
+ if (!data || errors) {
556
+ setLoading(false);
557
+ return;
558
+ }
559
+ // setChannelMessages((messages: any) => [
560
+ // ...messages,
561
+ // {
562
+ // ...data?.sendMessage,
563
+ // files: {
564
+ // totalCount: uploadedFiles.length,
565
+ // data: uploadedFiles,
566
+ // },
567
+ // },
568
+ // ]);
569
+ // setTotalCount((t: any) => t + 1);
570
+ setChannelToTop(channelToTop + 1);
571
+ setLoading(false);
572
+ setMsg('');
573
+ const msg = message == '' ? 'Send a file' : message;
574
+ fetchTokenAndSendPushNotification(msg, channelId);
575
+ },
576
+ });
577
+ }
578
+ } else {
579
+ setLoading(true);
580
+ await sendMsg({
484
581
  variables: {
485
- postId,
582
+ channelId,
583
+ content: message,
486
584
  },
487
- },
488
- createUploadLink: {
489
- variables: {
490
- postId,
585
+ update: (cache, { data, errors }: any) => {
586
+ if (!data || errors) {
587
+ setLoading(false);
588
+ return;
589
+ }
590
+ // setChannelMessages((messages: any) => [...messages, data?.sendMessage]);
591
+ // setTotalCount((t: any) => t + 1);
592
+ setChannelToTop(channelToTop + 1);
593
+ setLoading(false);
594
+ setMsg('');
595
+ fetchTokenAndSendPushNotification(message, channelId);
491
596
  },
492
- },
493
- });
494
- if (uploadResponse?.error) setLoading(false);
495
- const uploadedFiles = uploadResponse.data as unknown as IFileInfo[];
496
- if (uploadResponse.data) {
497
- setImage('');
498
- setFiles([]);
499
- setImages([]);
500
- setLoading(false);
597
+ });
501
598
  }
502
- setChannelMessages((messages: any) =>
503
- messages.map((message: any) => {
504
- if (message.id === postId) {
505
- return {
506
- ...message,
507
- files: {
508
- totalCount: uploadedFiles.length,
509
- data: uploadedFiles,
510
- },
511
- };
512
- }
513
- return message;
514
- }),
515
- );
516
- }
599
+ },
600
+ [mongooseObjectId, setChannelMessages, channelId, images, channelToTop, expoTokens],
601
+ );
602
+
603
+ const fetchTokenAndSendPushNotification = (message: any, channelId: any) => {
604
+ const givenName = auth?.profile?.given_name ?? '';
605
+ const familyName = auth?.profile?.family_name ?? '';
606
+ const fullName = givenName ? givenName + ' ' + familyName : '';
607
+ const title: String = fullName ? fullName : 'Message';
608
+ const body: String = message;
609
+ const notificationData: any = {
610
+ url: config.INBOX_MESSEGE_PATH,
611
+ params: { channelId, hideTabBar: true },
612
+ screen: 'DialogMessages',
613
+ };
614
+ refetchChannelDetail({ id: channelId?.toString() })?.then((res: any) => {
615
+ if (res?.data?.viewChannelDetail?.members?.length) {
616
+ const channelData: any =
617
+ res?.data?.viewChannelDetail?.members?.filter((mu: any) => mu?.user?.id != auth?.id) ?? [];
618
+ const tokens: any =
619
+ channelData
620
+ ?.map(
621
+ (u: any) =>
622
+ u?.user?.tokens
623
+ ?.filter((t: any) => t?.type == 'EXPO_NOTIFICATION_TOKEN')
624
+ ?.map((et: any) => et?.token) ?? [],
625
+ )
626
+ ?.flat(1)
627
+ ?.filter((t: any) => t)
628
+ ?.filter((value: any, index: any, array: any) => array.indexOf(value) === index) ?? [];
629
+ console.log('expo to', JSON.stringify(tokens));
630
+ if (tokens?.length > 0) {
631
+ const to: any = tokens?.length > 0 ? tokens : [];
632
+ sendPushNotification(title, body, notificationData, to);
633
+ }
634
+ }
635
+ });
517
636
  };
518
637
 
638
+ // const handleSend1 = async (message: string) => {
639
+ // if (!channelId) return;
640
+ // if (!message && message != ' ' && images.length == 0) return;
641
+
642
+ // setLoading(true);
643
+ // const { data } = await sendMsg({
644
+ // variables: {
645
+ // channelId,
646
+ // content: message,
647
+ // },
648
+ // update: (cache, { data, errors }: any) => {
649
+ // if (!data || errors) {
650
+ // setLoading(false);
651
+ // return;
652
+ // }
653
+ // setChannelMessages((messages: any) => [...messages, data?.sendMessage]);
654
+ // setTotalCount((t: any) => t + 1);
655
+ // setChannelToTop(channelToTop + 1);
656
+ // setLoading(false);
657
+ // setMsg('');
658
+ // const givenName = auth?.profile?.given_name ?? '';
659
+ // const familyName = auth?.profile?.family_name ?? '';
660
+ // const fullName = givenName ? givenName + ' ' + familyName : '';
661
+ // const title: String = fullName ? fullName : 'Message';
662
+ // const body: String = message;
663
+ // const notificationData: any = {
664
+ // url: config.INBOX_MESSEGE_PATH,
665
+ // params: { channelId, hideTabBar: true },
666
+ // screen: 'DialogMessages',
667
+ // };
668
+ // refetchChannelDetail({ id: channelId?.toString() })?.then((res: any) => {
669
+ // if (res?.data?.viewChannelDetail?.members?.length) {
670
+ // const channelData: any =
671
+ // res?.data?.viewChannelDetail?.members?.filter((mu: any) => mu?.user?.id != auth?.id) ?? [];
672
+ // const tokens: any =
673
+ // channelData
674
+ // ?.map(
675
+ // (u: any) =>
676
+ // u?.user?.tokens
677
+ // ?.filter((t: any) => t?.type == 'EXPO_NOTIFICATION_TOKEN')
678
+ // ?.map((et: any) => et?.token) ?? [],
679
+ // )
680
+ // ?.flat(1)
681
+ // ?.filter((t: any) => t)
682
+ // ?.filter((value: any, index: any, array: any) => array.indexOf(value) === index) ?? [];
683
+ // console.log('expo to', JSON.stringify(tokens));
684
+ // if (tokens?.length > 0) {
685
+ // const to: any = tokens?.length > 0 ? tokens : [];
686
+
687
+ // sendPushNotification(title, body, notificationData, to);
688
+ // }
689
+ // }
690
+ // });
691
+ // },
692
+ // });
693
+ // if (images && images.length > 0 && data?.sendMessage?.id) {
694
+ // const { id: postId } = data.sendMessage;
695
+ // setLoading(true);
696
+ // const uploadResponse = await startUpload({
697
+ // file: images,
698
+ // saveUploadedFile: {
699
+ // variables: {
700
+ // postId,
701
+ // },
702
+ // },
703
+ // createUploadLink: {
704
+ // variables: {
705
+ // postId,
706
+ // },
707
+ // },
708
+ // });
709
+ // if (uploadResponse?.error) setLoading(false);
710
+ // const uploadedFiles = uploadResponse.data as unknown as IFileInfo[];
711
+ // if (uploadResponse.data) {
712
+ // setImage('');
713
+ // setFiles([]);
714
+ // setImages([]);
715
+ // setLoading(false);
716
+ // }
717
+ // setChannelMessages((messages: any) =>
718
+ // messages.map((message: any) => {
719
+ // if (message.id === postId) {
720
+ // return {
721
+ // ...message,
722
+ // files: {
723
+ // totalCount: uploadedFiles.length,
724
+ // data: uploadedFiles,
725
+ // },
726
+ // };
727
+ // }
728
+ // return message;
729
+ // }),
730
+ // );
731
+ // }
732
+ // };
733
+
519
734
  const messageList = useMemo(() => {
520
735
  let currentDate = '';
521
736
  let res: any = [];
@@ -546,6 +761,7 @@ const ConversationViewComponent = ({ channelId }: any) => {
546
761
  (message.received = msg?.isRead);
547
762
  message.type = msg?.type;
548
763
  message.propsConfiguration = msg?.propsConfiguration;
764
+ message.replies = msg?.replies ?? [];
549
765
  res.push(message);
550
766
  });
551
767
  }
@@ -569,6 +785,8 @@ const ConversationViewComponent = ({ channelId }: any) => {
569
785
 
570
786
  const renderMessageText = (props: any) => {
571
787
  const { currentMessage } = props;
788
+ const lastReply: any = currentMessage?.replies?.data?.length > 0 ? currentMessage?.replies?.data?.[0] : null;
789
+
572
790
  if (currentMessage.type === 'ALERT') {
573
791
  const attachment = currentMessage?.propsConfiguration?.contents?.attachment;
574
792
  let action: string = '';
@@ -600,7 +818,60 @@ const ConversationViewComponent = ({ channelId }: any) => {
600
818
  </Box>
601
819
  );
602
820
  } else {
603
- return <MessageText {...props} textStyle={{ left: { marginLeft: 5 } }} />;
821
+ return (
822
+ <TouchableHighlight
823
+ underlayColor={'#c0c0c0'}
824
+ style={{ width: '100%' }}
825
+ onPress={() =>
826
+ navigation.navigate(config.THREAD_MESSEGE_PATH, {
827
+ channelId: channelId,
828
+ title: 'Message',
829
+ postParentId: currentMessage?._id,
830
+ isPostParentIdThread: true,
831
+ })
832
+ }
833
+ >
834
+ <>
835
+ <MessageText {...props} textStyle={{ left: { marginLeft: 5 } }} />
836
+ {currentMessage?.replies?.data?.length > 0 && (
837
+ <HStack space={1} px={1} alignItems={'center'}>
838
+ <HStack>
839
+ {currentMessage?.replies?.data
840
+ ?.filter(
841
+ (v: any, i: any, a: any) =>
842
+ a.findIndex((t: any) => t?.author?.id === v?.author?.id) === i,
843
+ )
844
+ ?.slice(0, 2)
845
+ ?.reverse()
846
+ ?.map((p: any, i: Number) => (
847
+ <Avatar
848
+ key={'key' + i}
849
+ bg={'transparent'}
850
+ size={6}
851
+ // top={i == 1 ? 4 : 0}
852
+ // right={i == 1 ? -2 : 0}
853
+ // zIndex={i == 1 ? 5 : 1}
854
+ _image={{ borderRadius: 6, borderWidth: 2, borderColor: '#fff' }}
855
+ source={{
856
+ uri: p?.author?.picture,
857
+ }}
858
+ >
859
+ {startCase(p?.author?.username?.charAt(0))}
860
+ </Avatar>
861
+ ))}
862
+ </HStack>
863
+ <Text fontSize={12} fontWeight={'bold'} color={'blue.800'}>
864
+ {currentMessage?.replies?.totalCount}{' '}
865
+ {currentMessage?.replies?.totalCount == 1 ? 'reply' : 'replies'}
866
+ </Text>
867
+ <Text fontSize={12} fontWeight={'bold'} color={'gray.500'}>
868
+ {lastReply ? createdAtText(lastReply?.createdAt) : ''}
869
+ </Text>
870
+ </HStack>
871
+ )}
872
+ </>
873
+ </TouchableHighlight>
874
+ );
604
875
  }
605
876
  };
606
877
 
@@ -682,13 +953,13 @@ const ConversationViewComponent = ({ channelId }: any) => {
682
953
 
683
954
  let onScroll = false;
684
955
 
685
- const onEndReached = () => {
686
- console.log('on end reached');
687
- if (!onScroll) return;
688
- // load messages, show ActivityIndicator
689
- onScroll = false;
690
- // setLoadingOldMessages(true);
691
- };
956
+ // const onEndReached = () => {
957
+ // console.log('on end reached');
958
+ // if (!onScroll) return;
959
+ // // load messages, show ActivityIndicator
960
+ // onScroll = false;
961
+ // // setLoadingOldMessages(true);
962
+ // };
692
963
 
693
964
  // const onMomentumScrollBegin = useCallback(
694
965
  // ({ nativeEvent }: any) => {
@@ -703,21 +974,22 @@ const ConversationViewComponent = ({ channelId }: any) => {
703
974
  // [loadingOldMessages, channelMessages],
704
975
  // );
705
976
 
706
- const onMomentumScrollBegin = ({ nativeEvent }: any) => {
707
- onScroll = true;
708
- console.log('scroll top');
709
- if (
710
- !loadingOldMessages &&
711
- (channelMessages?.length <= 10 || isCloseToTop(nativeEvent)) &&
712
- channelMessages?.length != totalCount
713
- ) {
714
- onFetchOld();
715
- }
716
- };
977
+ // const onMomentumScrollBegin = ({ nativeEvent }: any) => {
978
+ // onScroll = true;
979
+ // console.log('scroll top');
980
+ // if (
981
+ // !loadingOldMessages &&
982
+ // (channelMessages?.length <= 10 || isCloseToTop(nativeEvent)) &&
983
+ // channelMessages?.length != totalCount
984
+ // ) {
985
+ // onFetchOld();
986
+ // }
987
+ // };
717
988
 
718
989
  return (
719
990
  <>
720
- {loadingOldMessages && <Spinner />}
991
+ {loadEarlierMsg && <Spinner />}
992
+
721
993
  <GiftedChat
722
994
  wrapInSafeArea={false}
723
995
  renderLoading={() => <Spinner />}
@@ -726,7 +998,7 @@ const ConversationViewComponent = ({ channelId }: any) => {
726
998
  // onEndReached: onEndReached,
727
999
  // onEndReachedThreshold: 0.5,
728
1000
  // onMomentumScrollBegin: onMomentumScrollBegin,
729
- // }}////
1001
+ // }}
730
1002
  // listViewProps={{
731
1003
  // scrollEventThrottle: 400,
732
1004
  // onScroll: ({ nativeEvent }) => { console.log('scroll')
@@ -746,13 +1018,25 @@ const ConversationViewComponent = ({ channelId }: any) => {
746
1018
  }}
747
1019
  isTyping={true}
748
1020
  alwaysShowSend={loading ? false : true}
749
- onLoadEarlier={onFetchOld}
750
- infiniteScroll={true}
1021
+ //onLoadEarlier={onFetchOld}
1022
+ //infiniteScroll={true}
751
1023
  renderSend={renderSend}
752
1024
  loadEarlier={data?.messages?.totalCount > channelMessages.length}
753
- //isLoadingEarlier={isLoadingEarlier}
1025
+ isLoadingEarlier={loadEarlierMsg}
754
1026
  //extraData={{ isLoadingEarlier: loadingOldMessages }}
755
- //renderLoadEarlier={() => <Spinner />}}
1027
+ renderLoadEarlier={() =>
1028
+ !loadEarlierMsg && (
1029
+ <Center py={2}>
1030
+ <Button
1031
+ onPress={() => onFetchOld(data, channelMessages)}
1032
+ variant={'outline'}
1033
+ _text={{ color: 'black', fontSize: 15, fontWeight: 'bold' }}
1034
+ >
1035
+ Load earlier messages
1036
+ </Button>
1037
+ </Center>
1038
+ )
1039
+ }
756
1040
  renderMessageText={renderMessageText}
757
1041
  minInputToolbarHeight={50}
758
1042
  renderActions={renderActions}