@messenger-box/platform-mobile 0.0.1-alpha.391 → 0.0.1-alpha.392

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,4 +1,4 @@
1
- import React, { useCallback, useEffect, useMemo, useState } from 'react';
1
+ import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react';
2
2
  import {
3
3
  Box,
4
4
  Button,
@@ -35,6 +35,8 @@ import {
35
35
  IPreDefinedRole,
36
36
  useSendExpoNotificationOnPostMutation,
37
37
  IPost,
38
+ OnThreadChatMessageAddedDocument as CHAT_MESSAGE_ADDED,
39
+ usePostThreadMessagesQuery,
38
40
  } from '@messenger-box/platform-client';
39
41
  import { IExpoNotificationData, IFileInfo } from '@messenger-box/core';
40
42
  import { config } from '../config';
@@ -73,6 +75,10 @@ export interface AlertMessageAttachmentsInterface {
73
75
  };
74
76
  }
75
77
 
78
+ interface IThreadSubscriptionHandlerProps {
79
+ subscribeToNewMessages: () => any;
80
+ }
81
+
76
82
  const ThreadConversationViewComponent = ({ channelId, postParentId, isPostParentIdThread, role }: any) => {
77
83
  const { params } = useRoute<any>();
78
84
  const [channelToTop, setChannelToTop] = useState(0);
@@ -96,9 +102,12 @@ const ThreadConversationViewComponent = ({ channelId, postParentId, isPostParent
96
102
  const [parentId, setParentId] = useState<any>(postParentId);
97
103
  const { startUpload } = useUploadFilesNative();
98
104
  const [threadPost, setThreadPost] = useState<any[]>([]);
99
- const { data: mongooseObjectId,refetch:refetchNewPostId } = useGetNewMongooseObjectIdQuery({
105
+ const [skip, setSkip] = useState(0);
106
+ const [isScrollToBottom, setIsScrollToBottom] = useState(false);
107
+ const threadMessageListRef = useRef<any>(null);
108
+ const { data: mongooseObjectId, refetch: refetchNewPostId } = useGetNewMongooseObjectIdQuery({
100
109
  fetchPolicy: 'network-only',
101
- // pollInterval: 5000,
110
+ // pollInterval: 5000,
102
111
  });
103
112
 
104
113
  const {
@@ -129,26 +138,20 @@ const ThreadConversationViewComponent = ({ channelId, postParentId, isPostParent
129
138
  data,
130
139
  loading: messageLoading,
131
140
  refetch,
132
- }: any = useMessagesQuery({
141
+ fetchMore: fetchMoreMessages,
142
+ subscribeToMore,
143
+ }: any = usePostThreadMessagesQuery({
133
144
  variables: {
134
145
  channelId: !parentId || parentId == 0 ? null : channelId?.toString(),
135
146
  parentId: !parentId || parentId == 0 ? null : parentId?.toString(),
136
147
  limit: MESSAGES_PER_PAGE,
148
+ skip: skip,
137
149
  },
138
150
  skip: !channelId,
139
151
  fetchPolicy: 'cache-and-network',
152
+ refetchWritePolicy: 'merge',
140
153
  });
141
154
 
142
- // const { data: checkForMessages }: any = useCheckForNewMessagesQuery({
143
- // variables: {
144
- // channelId: !parentId || parentId == 0 ? null : channelId?.toString(),
145
- // parentId: !parentId || parentId == 0 ? null : parentId?.toString(),
146
- // },
147
- // skip: !channelId,
148
- // fetchPolicy: 'network-only',
149
- // pollInterval: 5000,
150
- // });
151
-
152
155
  useFocusEffect(
153
156
  React.useCallback(() => {
154
157
  navigation?.setOptions({ title: params?.title ?? 'Thread' });
@@ -163,19 +166,22 @@ const ThreadConversationViewComponent = ({ channelId, postParentId, isPostParent
163
166
  channelId: !parentId || parentId == 0 ? null : channelId?.toString(),
164
167
  parentId: !parentId || parentId == 0 ? null : parentId?.toString(),
165
168
  limit: MESSAGES_PER_PAGE,
169
+ skip: 0,
166
170
  }).then(({ data }) => {
167
171
  if (!data?.messages) {
168
172
  return;
169
173
  }
170
174
  const { data: messages, totalCount }: any = data.messages;
171
175
  setTotalCount(totalCount);
172
- setChannelMessages((oldMessages: any) => uniqBy([...oldMessages, ...messages], ({ id }) => id));
176
+ setChannelMessages(messages);
177
+ //setChannelMessages((oldMessages: any) => uniqBy([...oldMessages, ...messages], ({ id }) => id));
173
178
  });
174
179
  return () => {
175
180
  setTotalCount(0);
176
181
  setChannelMessages([]);
182
+ setThreadPost([]);
177
183
  };
178
- }, []),
184
+ }, [channelId, parentId]),
179
185
  );
180
186
 
181
187
  useEffect(() => {
@@ -195,25 +201,41 @@ const ThreadConversationViewComponent = ({ channelId, postParentId, isPostParent
195
201
  }, [parentId]);
196
202
 
197
203
  useEffect(() => {
198
- if (threadMessagesData?.threadMessages) {
204
+ if (threadMessagesData?.threadMessages?.data) {
199
205
  const { data: threads, totalCount: threadTotalCount }: any = threadMessagesData?.threadMessages;
200
206
  const threadMessage = threads?.map((t: any) => t?.post);
201
- setThreadPost(threadMessage);
207
+
208
+ if (threadPost?.length == 0) {
209
+ setThreadPost(threadMessage);
210
+ setChannelMessages((oldMessages: any) => uniqBy([...threadMessage, ...oldMessages], ({ id }) => id));
211
+ }
202
212
  // if (!isPostParentIdThread) {
203
213
  // // setTotalCount((pc: any) => pc + threadTotalCount);
204
214
  // setChannelMessages((oldMessages: any) => uniqBy([...threadMessage, ...oldMessages], ({ id }) => id));
205
215
  // }
206
216
  }
207
- }, [threadMessagesData, isPostParentIdThread]);
217
+ }, [threadMessagesData, threadPost, isPostParentIdThread]);
218
+
219
+ // React.useEffect(() => {
220
+ // if (newThreadMsg) {
221
+ // console.log('newThreadMsg');
222
+ // const msg = newThreadMsg?.threadChatMessageAdded;
223
+ // setTotalCount((preCount: any) => preCount + 1);
224
+ // setChannelMessages((oldMessages: any) => uniqBy([...oldMessages, msg], ({ id }) => id));
225
+ // }
226
+ // }, [newThreadMsg]);
208
227
 
209
228
  React.useEffect(() => {
210
229
  if (newThreadMsg) {
211
230
  console.log('newThreadMsg');
212
- const msg = newThreadMsg?.threadChatMessageAdded;
213
- setTotalCount((preCount: any) => preCount + 1);
214
- setChannelMessages((oldMessages: any) => uniqBy([...oldMessages, msg], ({ id }) => id));
231
+ refetch({
232
+ channelId: !parentId || parentId == 0 ? null : channelId?.toString(),
233
+ parentId: !parentId || parentId == 0 ? null : parentId?.toString(),
234
+ limit: MESSAGES_PER_PAGE,
235
+ skip: 0,
236
+ });
215
237
  }
216
- }, [newThreadMsg]);
238
+ }, [newThreadMsg, skip, parentId]);
217
239
 
218
240
  // useEffect(() => {
219
241
  // if (data?.messages?.data && (loadingOldMessages || channelMessages.length === 0)) {
@@ -226,21 +248,49 @@ const ThreadConversationViewComponent = ({ channelId, postParentId, isPostParent
226
248
  // }
227
249
  // }, [data, loadingOldMessages, channelMessages, totalCount]);
228
250
 
229
- useEffect(() => {
230
- if ((data?.messages?.data && channelMessages.length === 0) || (data?.messages?.data && loadingOldMessages)) {
251
+ // useEffect(() => {
252
+ // if ((data?.messages?.data && channelMessages.length === 0) || (data?.messages?.data && loadingOldMessages)) {
253
+ // const { data: messages, totalCount: messeageTotalCount } = data.messages;
254
+ // if (messages && messages.length > 0) {
255
+ // setChannelMessages((oldMessages: any) => uniqBy([...messages, ...oldMessages], ({ id }) => id));
256
+ // setTotalCount(messeageTotalCount);
257
+ // }
258
+ // setLoadEarlierMsg(false);
259
+ // if (loadingOldMessages) setLoadingOldMessages(false);
260
+ // }
261
+ // if (threadPost?.length && data?.messages?.totalCount == channelMessages.length) {
262
+ // // setTotalCount((pc: any) => pc + threadTotalCount);
263
+ // setChannelMessages((oldMessages: any) => uniqBy([...threadPost, ...oldMessages], ({ id }) => id));
264
+ // }
265
+ // }, [data, loadingOldMessages, channelMessages, threadPost]);
266
+
267
+ React.useEffect(() => {
268
+ if (data?.messages?.data) {
231
269
  const { data: messages, totalCount: messeageTotalCount } = data.messages;
232
- if (messages && messages.length > 0) {
270
+ if (
271
+ (messages && messages.length > 0 && messeageTotalCount > totalCount) ||
272
+ (messages && messages.length > 0 && (loadingOldMessages || channelMessages.length === 0))
273
+ ) {
233
274
  setChannelMessages((oldMessages: any) => uniqBy([...messages, ...oldMessages], ({ id }) => id));
234
275
  setTotalCount(messeageTotalCount);
276
+ setLoadEarlierMsg(false);
277
+ }
278
+
279
+ if (loadingOldMessages && channelMessages) setLoadingOldMessages(false);
280
+
281
+ if (
282
+ channelMessages &&
283
+ channelMessages?.length == MESSAGES_PER_PAGE &&
284
+ totalCount > channelMessages?.length
285
+ ) {
286
+ onFetchOld();
235
287
  }
236
- setLoadEarlierMsg(false);
237
- if (loadingOldMessages) setLoadingOldMessages(false);
238
- }
239
- if (threadPost?.length && data?.messages?.totalCount == channelMessages.length) {
240
- // setTotalCount((pc: any) => pc + threadTotalCount);
241
- setChannelMessages((oldMessages: any) => uniqBy([...threadPost, ...oldMessages], ({ id }) => id));
242
288
  }
243
- }, [data, loadingOldMessages, channelMessages, threadPost]);
289
+
290
+ // if (threadPost?.length > 0 && channelMessages.length == (0 || MESSAGES_PER_PAGE)) {
291
+ // setChannelMessages((oldMessages: any) => uniqBy([...threadPost, ...oldMessages], ({ id }) => id));
292
+ // }
293
+ }, [data, loadingOldMessages, totalCount, channelMessages, isScrollToBottom]);
244
294
 
245
295
  // useEffect(() => {
246
296
  // if (
@@ -280,16 +330,40 @@ const ThreadConversationViewComponent = ({ channelId, postParentId, isPostParent
280
330
  // }
281
331
  // }, [data, channelMessages]);
282
332
 
283
- const onFetchOld = useCallback((data: any, channelMessages: any) => {
284
- if (data?.messages?.totalCount > channelMessages.length) {
333
+ const scrollToBottom = React.useCallback(() => {
334
+ if (threadMessageListRef?.current) {
335
+ setIsScrollToBottom(false);
336
+ threadMessageListRef.current.scrollTop = threadMessageListRef.current.scrollHeight;
337
+ }
338
+ }, [threadMessageListRef]);
339
+
340
+ // const onFetchOld = useCallback((data: any, channelMessages: any) => {
341
+ // if (data?.messages?.totalCount > channelMessages.length) {
342
+ // setLoadEarlierMsg(true);
343
+ // refetch({
344
+ // channelId: !parentId || parentId == 0 ? null : channelId?.toString(),
345
+ // parentId: !parentId || parentId == 0 ? null : parentId?.toString(),
346
+ // skip: channelMessages.length,
347
+ // })?.then((res: any) => setLoadingOldMessages(true));
348
+ // }
349
+ // }, []);
350
+
351
+ const onFetchOld = useCallback(() => {
352
+ if (totalCount > channelMessages.length && !loadingOldMessages) {
353
+ setSkip(channelMessages.length);
285
354
  setLoadEarlierMsg(true);
286
- refetch({
287
- channelId: !parentId || parentId == 0 ? null : channelId?.toString(),
288
- parentId: !parentId || parentId == 0 ? null : parentId?.toString(),
289
- skip: channelMessages.length,
355
+ fetchMoreMessages({
356
+ variables: {
357
+ channelId: channelId?.toString(),
358
+ parentId: null,
359
+ skip: channelMessages.length,
360
+ },
290
361
  })?.then((res: any) => setLoadingOldMessages(true));
362
+ // refetch({ channelId: channelId?.toString(), parentId: null, skip: channelMessages.length })?.then(
363
+ // (res: any) => setLoadingOldMessages(true),
364
+ // );
291
365
  }
292
- }, []);
366
+ }, [totalCount, channelMessages]);
293
367
 
294
368
  // const isCloseToTop = ({ layoutMeasurement, contentOffset, contentSize }) => {
295
369
  // return contentOffset.y <= 100; // 100px from top
@@ -366,7 +440,7 @@ const ThreadConversationViewComponent = ({ channelId, postParentId, isPostParent
366
440
  if (images && images.length > 0) {
367
441
  const newPostId = await refetchNewPostId();
368
442
  const postId: any = newPostId?.data?.getNewMongooseObjectId?.toString();
369
- // const postId: any = mongooseObjectId?.getNewMongooseObjectId;
443
+ // const postId: any = mongooseObjectId?.getNewMongooseObjectId;
370
444
  setLoading(true);
371
445
  const uploadResponse = await startUpload({
372
446
  file: images,
@@ -408,18 +482,18 @@ const ThreadConversationViewComponent = ({ channelId, postParentId, isPostParent
408
482
  const responseMessage = data?.sendThreadMessage?.lastMessage;
409
483
  if (!parentId || parentId == 0) {
410
484
  setParentId(responseMessage?.id);
411
- setChannelMessages((messages: any) => [
412
- ...messages,
413
- {
414
- ...responseMessage,
415
- files: {
416
- totalCount: uploadedFiles.length,
417
- data: uploadedFiles,
418
- },
419
- },
420
- ]);
421
-
422
- setTotalCount((t: any) => t + 1);
485
+ // setChannelMessages((messages: any) => [
486
+ // ...messages,
487
+ // {
488
+ // ...responseMessage,
489
+ // files: {
490
+ // totalCount: uploadedFiles.length,
491
+ // data: uploadedFiles,
492
+ // },
493
+ // },
494
+ // ]);
495
+
496
+ // setTotalCount((t: any) => t + 1);
423
497
  }
424
498
 
425
499
  setChannelToTop(channelToTop + 1);
@@ -458,8 +532,8 @@ const ThreadConversationViewComponent = ({ channelId, postParentId, isPostParent
458
532
  const responseMessage = data?.sendThreadMessage?.lastMessage;
459
533
  if (!parentId || parentId == 0) {
460
534
  setParentId(responseMessage?.id);
461
- setChannelMessages((messages: any) => [...messages, responseMessage]);
462
- setTotalCount((t: any) => t + 1);
535
+ // setChannelMessages((messages: any) => [...messages, responseMessage]);
536
+ // setTotalCount((t: any) => t + 1);
463
537
  }
464
538
  setChannelToTop(channelToTop + 1);
465
539
  setLoading(false);
@@ -719,10 +793,28 @@ const ThreadConversationViewComponent = ({ channelId, postParentId, isPostParent
719
793
  return <SlackMessage {...props} isShowImageViewer={isShowImageViewer} setImageViewer={setImageViewerObject} />;
720
794
  };
721
795
 
796
+ let onScroll = false;
797
+
798
+ const onMomentumScrollBegin = ({ nativeEvent }: any) => {
799
+ onScroll = true;
800
+ console.log('scroll top');
801
+ if (!loadingOldMessages && isCloseToTop(nativeEvent) && totalCount > channelMessages?.length) {
802
+ onFetchOld();
803
+ }
804
+ };
805
+
806
+ const onEndReached = () => {
807
+ console.log('on end reached');
808
+ if (!onScroll) return;
809
+ // load messages, show ActivityIndicator
810
+ onScroll = false;
811
+ // setLoadingOldMessages(true);
812
+ };
813
+
722
814
  return (
723
815
  <>
724
- {/* {loadingOldMessages && <Spinner />} */}
725
- {loadEarlierMsg && <Spinner />}
816
+ {(loadingOldMessages || loadEarlierMsg) && <Spinner />}
817
+ {/* {loadEarlierMsg && <Spinner />} */}
726
818
  {isPostParentIdThread && (
727
819
  <>
728
820
  {threadPost?.length > 0 && (
@@ -768,9 +860,15 @@ const ThreadConversationViewComponent = ({ channelId, postParentId, isPostParent
768
860
  </>
769
861
  )}
770
862
  <GiftedChat
863
+ ref={threadMessageListRef}
771
864
  wrapInSafeArea={false}
772
865
  renderLoading={() => <Spinner />}
773
866
  messages={messageList}
867
+ listViewProps={{
868
+ onEndReached: onEndReached,
869
+ onEndReachedThreshold: 0.5,
870
+ onMomentumScrollBegin: onMomentumScrollBegin,
871
+ }}
774
872
  onSend={(messages) => handleSend(messages[0]?.text ?? ' ')}
775
873
  text={msg ? msg : ' '}
776
874
  onInputTextChanged={(text) => setMsg(text)}
@@ -784,32 +882,69 @@ const ThreadConversationViewComponent = ({ channelId, postParentId, isPostParent
784
882
  // onLoadEarlier={onFetchOld}
785
883
  infiniteScroll={true}
786
884
  renderSend={renderSend}
787
- loadEarlier={data?.messages?.totalCount > channelMessages.length}
788
- isLoadingEarlier={loadEarlierMsg}
789
- renderLoadEarlier={() =>
790
- !loadEarlierMsg && (
791
- <Center py={2}>
792
- <Button
793
- onPress={() => onFetchOld(data, channelMessages)}
794
- variant={'outline'}
795
- _text={{ color: 'black', fontSize: 15, fontWeight: 'bold' }}
796
- >
797
- Load earlier messages
798
- </Button>
799
- </Center>
800
- )
801
- }
885
+ // loadEarlier={data?.messages?.totalCount > channelMessages.length}
886
+ // isLoadingEarlier={loadEarlierMsg}
887
+ // renderLoadEarlier={() =>
888
+ // !loadEarlierMsg && (
889
+ // <Center py={2}>
890
+ // <Button
891
+ // onPress={() => onFetchOld(channelMessages?.length)}
892
+ // variant={'outline'}
893
+ // _text={{ color: 'black', fontSize: 15, fontWeight: 'bold' }}
894
+ // >
895
+ // Load earlier messages
896
+ // </Button>
897
+ // </Center>
898
+ // )
899
+ // }
802
900
  renderMessageText={renderMessageText}
803
901
  minInputToolbarHeight={50}
804
902
  renderActions={renderActions}
805
903
  renderAccessory={renderAccessory}
806
904
  renderMessage={renderMessage}
807
905
  renderChatFooter={() => (
808
- <ImageViewerModal
809
- isVisible={isShowImageViewer}
810
- setVisible={setImageViewer}
811
- modalContent={modalContent}
812
- />
906
+ <>
907
+ <ImageViewerModal
908
+ isVisible={isShowImageViewer}
909
+ setVisible={setImageViewer}
910
+ modalContent={modalContent}
911
+ />
912
+ <SubscriptionHandler
913
+ subscribeToNewMessages={() =>
914
+ subscribeToMore({
915
+ document: CHAT_MESSAGE_ADDED,
916
+ variables: {
917
+ channelId: channelId?.toString(),
918
+ postParentId: !parentId || parentId == 0 ? null : parentId?.toString(),
919
+ },
920
+ updateQuery: (prev, { subscriptionData }: any) => {
921
+ if (!subscriptionData.data) return prev;
922
+
923
+ const newMessage: any = subscriptionData?.data?.threadChatMessageAdded;
924
+ const mergedData = prev?.messages?.data
925
+ ? [...prev.messages.data, newMessage]
926
+ : [];
927
+ const totalMsgCount = prev?.messages?.totalCount + 1;
928
+ const merged = {
929
+ ...prev,
930
+ messages: {
931
+ ...prev?.messages,
932
+ data: mergedData,
933
+ totalCount: totalMsgCount,
934
+ },
935
+ };
936
+ return merged;
937
+ // return Object.assign({}, prev, {
938
+ // messages: {
939
+ // data: [...prev.messages.data, newMessage],
940
+ // totalCount: prev.messages.totalCount + 1,
941
+ // },
942
+ // });
943
+ },
944
+ })
945
+ }
946
+ />
947
+ </>
813
948
  )}
814
949
  messagesContainerStyle={messageList?.length == 0 && { transform: [{ scaleY: -1 }] }}
815
950
  renderChatEmpty={() => (
@@ -834,4 +969,9 @@ const ThreadConversationViewComponent = ({ channelId, postParentId, isPostParent
834
969
  );
835
970
  };
836
971
 
972
+ const SubscriptionHandler = ({ subscribeToNewMessages }: IThreadSubscriptionHandlerProps) => {
973
+ useEffect(() => subscribeToNewMessages(), []);
974
+ return <></>;
975
+ };
976
+
837
977
  export const ThreadConversationView = React.memo(ThreadConversationViewComponent);