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

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