stream-chat-react-native-core 6.7.3-beta.1 → 6.7.3-beta.3
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/lib/commonjs/components/Channel/Channel.js +296 -293
- package/lib/commonjs/components/Channel/Channel.js.map +1 -1
- package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js +133 -147
- package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js.map +1 -1
- package/lib/commonjs/components/KeyboardCompatibleView/KeyboardCompatibleView.js +7 -12
- package/lib/commonjs/components/KeyboardCompatibleView/KeyboardCompatibleView.js.map +1 -1
- package/lib/commonjs/components/MessageList/MessageList.js +167 -179
- package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
- package/lib/commonjs/components/MessageList/hooks/useMessageList.js +60 -37
- package/lib/commonjs/components/MessageList/hooks/useMessageList.js.map +1 -1
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +450 -459
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/commonjs/contexts/messagesContext/MessagesContext.js.map +1 -1
- package/lib/commonjs/hooks/index.js +11 -0
- package/lib/commonjs/hooks/index.js.map +1 -1
- package/lib/commonjs/hooks/useStableCallback.js +13 -0
- package/lib/commonjs/hooks/useStableCallback.js.map +1 -0
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Channel/Channel.js +296 -293
- package/lib/module/components/Channel/Channel.js.map +1 -1
- package/lib/module/components/Channel/hooks/useMessageListPagination.js +133 -147
- package/lib/module/components/Channel/hooks/useMessageListPagination.js.map +1 -1
- package/lib/module/components/KeyboardCompatibleView/KeyboardCompatibleView.js +7 -12
- package/lib/module/components/KeyboardCompatibleView/KeyboardCompatibleView.js.map +1 -1
- package/lib/module/components/MessageList/MessageList.js +167 -179
- package/lib/module/components/MessageList/MessageList.js.map +1 -1
- package/lib/module/components/MessageList/hooks/useMessageList.js +60 -37
- package/lib/module/components/MessageList/hooks/useMessageList.js.map +1 -1
- package/lib/module/contexts/messageInputContext/MessageInputContext.js +450 -459
- package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/module/contexts/messagesContext/MessagesContext.js.map +1 -1
- package/lib/module/hooks/index.js +11 -0
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/useStableCallback.js +13 -0
- package/lib/module/hooks/useStableCallback.js.map +1 -0
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
- package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts +3 -3
- package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts.map +1 -1
- package/lib/typescript/components/KeyboardCompatibleView/KeyboardCompatibleView.d.ts +3 -0
- package/lib/typescript/components/KeyboardCompatibleView/KeyboardCompatibleView.d.ts.map +1 -1
- package/lib/typescript/components/MessageList/MessageList.d.ts.map +1 -1
- package/lib/typescript/components/MessageList/hooks/useMessageList.d.ts +4 -0
- package/lib/typescript/components/MessageList/hooks/useMessageList.d.ts.map +1 -1
- package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts.map +1 -1
- package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts +1 -1
- package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts.map +1 -1
- package/lib/typescript/hooks/index.d.ts +1 -0
- package/lib/typescript/hooks/index.d.ts.map +1 -1
- package/lib/typescript/hooks/useStableCallback.d.ts +26 -0
- package/lib/typescript/hooks/useStableCallback.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/components/Channel/Channel.tsx +462 -431
- package/src/components/Channel/__tests__/Channel.test.js +8 -3
- package/src/components/Channel/hooks/useMessageListPagination.tsx +152 -147
- package/src/components/KeyboardCompatibleView/KeyboardCompatibleView.tsx +6 -4
- package/src/components/MessageList/MessageList.tsx +147 -112
- package/src/components/MessageList/hooks/useMessageList.ts +69 -38
- package/src/contexts/messageInputContext/MessageInputContext.tsx +293 -267
- package/src/contexts/messageInputContext/__tests__/pickFile.test.tsx +2 -1
- package/src/contexts/messagesContext/MessagesContext.tsx +1 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useStableCallback.ts +37 -0
- package/src/version.json +1 -1
|
@@ -53,6 +53,7 @@ import {
|
|
|
53
53
|
import { mergeThemes, ThemeProvider, useTheme } from '../../contexts/themeContext/ThemeContext';
|
|
54
54
|
import { ThreadContextValue, useThreadContext } from '../../contexts/threadContext/ThreadContext';
|
|
55
55
|
|
|
56
|
+
import { useStableCallback } from '../../hooks';
|
|
56
57
|
import { DefaultStreamChatGenerics, FileTypes } from '../../types/types';
|
|
57
58
|
|
|
58
59
|
// This is just to make sure that the scrolling happens in a different task queue.
|
|
@@ -362,6 +363,14 @@ const MessageListWithContext = <
|
|
|
362
363
|
|
|
363
364
|
const [autoscrollToRecent, setAutoscrollToRecent] = useState(false);
|
|
364
365
|
|
|
366
|
+
const maintainVisibleContentPosition = useMemo(
|
|
367
|
+
() => ({
|
|
368
|
+
autoscrollToTopThreshold: autoscrollToRecent ? 10 : undefined,
|
|
369
|
+
minIndexForVisible: 1,
|
|
370
|
+
}),
|
|
371
|
+
[autoscrollToRecent],
|
|
372
|
+
);
|
|
373
|
+
|
|
365
374
|
/**
|
|
366
375
|
* We want to call onEndReached and onStartReached only once, per content length.
|
|
367
376
|
* We keep track of calls to these functions per content length, with following trackers.
|
|
@@ -392,8 +401,9 @@ const MessageListWithContext = <
|
|
|
392
401
|
*/
|
|
393
402
|
const messageIdLastScrolledToRef = useRef<string>(undefined);
|
|
394
403
|
const [hasMoved, setHasMoved] = useState(false);
|
|
395
|
-
const
|
|
396
|
-
getLastReceivedMessage(processedMessageList)?.id,
|
|
404
|
+
const lastReceivedId = useMemo(
|
|
405
|
+
() => getLastReceivedMessage(processedMessageList)?.id,
|
|
406
|
+
[processedMessageList],
|
|
397
407
|
);
|
|
398
408
|
const [scrollToBottomButtonVisible, setScrollToBottomButtonVisible] = useState(false);
|
|
399
409
|
|
|
@@ -404,7 +414,7 @@ const MessageListWithContext = <
|
|
|
404
414
|
const channelRef = useRef(channel);
|
|
405
415
|
channelRef.current = channel;
|
|
406
416
|
|
|
407
|
-
const updateStickyHeaderDateIfNeeded = (viewableItems: ViewToken[]) => {
|
|
417
|
+
const updateStickyHeaderDateIfNeeded = useStableCallback((viewableItems: ViewToken[]) => {
|
|
408
418
|
if (!viewableItems.length) {
|
|
409
419
|
return;
|
|
410
420
|
}
|
|
@@ -431,12 +441,12 @@ const MessageListWithContext = <
|
|
|
431
441
|
setStickyHeaderDate(lastItem.item.created_at);
|
|
432
442
|
}
|
|
433
443
|
}
|
|
434
|
-
};
|
|
444
|
+
});
|
|
435
445
|
|
|
436
446
|
/**
|
|
437
447
|
* This function should show or hide the unread indicator depending on the
|
|
438
448
|
*/
|
|
439
|
-
const updateStickyUnreadIndicator = (viewableItems: ViewToken[]) => {
|
|
449
|
+
const updateStickyUnreadIndicator = useStableCallback((viewableItems: ViewToken[]) => {
|
|
440
450
|
if (!viewableItems.length) {
|
|
441
451
|
setIsUnreadNotificationOpen(false);
|
|
442
452
|
return;
|
|
@@ -482,7 +492,7 @@ const MessageListWithContext = <
|
|
|
482
492
|
setIsUnreadNotificationOpen(false);
|
|
483
493
|
}
|
|
484
494
|
}
|
|
485
|
-
};
|
|
495
|
+
});
|
|
486
496
|
|
|
487
497
|
/**
|
|
488
498
|
* FlatList doesn't accept changeable function for onViewableItemsChanged prop.
|
|
@@ -580,9 +590,6 @@ const MessageListWithContext = <
|
|
|
580
590
|
]);
|
|
581
591
|
|
|
582
592
|
useEffect(() => {
|
|
583
|
-
const lastReceivedMessage = getLastReceivedMessage(processedMessageList);
|
|
584
|
-
setLastReceivedId(lastReceivedMessage?.id);
|
|
585
|
-
|
|
586
593
|
/**
|
|
587
594
|
* Scroll down when
|
|
588
595
|
* created_at timestamp of top message before update is lesser than created_at timestamp of top message after update - channel has resynced
|
|
@@ -678,7 +685,7 @@ const MessageListWithContext = <
|
|
|
678
685
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
679
686
|
}, [channel, rawMessageList, threadList]);
|
|
680
687
|
|
|
681
|
-
const goToMessage = async (messageId: string) => {
|
|
688
|
+
const goToMessage = useStableCallback(async (messageId: string) => {
|
|
682
689
|
const indexOfParentInMessageList = processedMessageList.findIndex(
|
|
683
690
|
(message) => message?.id === messageId,
|
|
684
691
|
);
|
|
@@ -706,7 +713,7 @@ const MessageListWithContext = <
|
|
|
706
713
|
} catch (e) {
|
|
707
714
|
console.warn('Error while scrolling to message', e);
|
|
708
715
|
}
|
|
709
|
-
};
|
|
716
|
+
});
|
|
710
717
|
|
|
711
718
|
/**
|
|
712
719
|
* Check if a messageId needs to be scrolled to after list loads, and scroll to it
|
|
@@ -749,78 +756,99 @@ const MessageListWithContext = <
|
|
|
749
756
|
// TODO: do not apply on RN 0.73 and above
|
|
750
757
|
const shouldApplyAndroidWorkaround = inverted && Platform.OS === 'android';
|
|
751
758
|
|
|
752
|
-
const renderItem = (
|
|
753
|
-
index,
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
item: MessageType<StreamChatGenerics>;
|
|
758
|
-
}) => {
|
|
759
|
-
if (!channel || channel.disconnected || (!channel.initialized && !channel.offlineMode)) {
|
|
760
|
-
return null;
|
|
761
|
-
}
|
|
759
|
+
const renderItem = useCallback(
|
|
760
|
+
({ index, item: message }: { index: number; item: MessageType<StreamChatGenerics> }) => {
|
|
761
|
+
if (!channel || channel.disconnected || (!channel.initialized && !channel.offlineMode)) {
|
|
762
|
+
return null;
|
|
763
|
+
}
|
|
762
764
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
765
|
+
const createdAtTimestamp = message.created_at && new Date(message.created_at).getTime();
|
|
766
|
+
const lastReadTimestamp = channelUnreadState?.last_read.getTime();
|
|
767
|
+
const isNewestMessage = index === 0;
|
|
768
|
+
const isLastReadMessage =
|
|
769
|
+
channelUnreadState?.last_read_message_id === message.id ||
|
|
770
|
+
(!channelUnreadState?.unread_messages && createdAtTimestamp === lastReadTimestamp);
|
|
771
|
+
|
|
772
|
+
const showUnreadSeparator =
|
|
773
|
+
isLastReadMessage &&
|
|
774
|
+
!isNewestMessage &&
|
|
775
|
+
// The `channelUnreadState?.first_unread_message_id` is here for sent messages unread label
|
|
776
|
+
(!!channelUnreadState?.first_unread_message_id || !!channelUnreadState?.unread_messages);
|
|
777
|
+
|
|
778
|
+
const showUnreadUnderlay = !!shouldShowUnreadUnderlay && showUnreadSeparator;
|
|
779
|
+
|
|
780
|
+
const wrapMessageInTheme = client.userID === message.user?.id && !!myMessageTheme;
|
|
781
|
+
const renderDateSeperator = isMessageWithStylesReadByAndDateSeparator(message) &&
|
|
782
|
+
message.dateSeparator && <InlineDateSeparator date={message.dateSeparator} />;
|
|
783
|
+
const renderMessage = (
|
|
784
|
+
<Message
|
|
785
|
+
goToMessage={goToMessage}
|
|
786
|
+
groupStyles={
|
|
787
|
+
isMessageWithStylesReadByAndDateSeparator(message) ? message.groupStyles : []
|
|
788
|
+
}
|
|
789
|
+
isTargetedMessage={highlightedMessageId === message.id}
|
|
790
|
+
lastReceivedId={
|
|
791
|
+
lastReceivedId === message.id || message.quoted_message_id ? lastReceivedId : undefined
|
|
792
|
+
}
|
|
793
|
+
message={message}
|
|
794
|
+
onThreadSelect={onThreadSelect}
|
|
795
|
+
showUnreadUnderlay={showUnreadUnderlay}
|
|
796
|
+
style={[messageContainer]}
|
|
797
|
+
threadList={threadList}
|
|
798
|
+
/>
|
|
799
|
+
);
|
|
796
800
|
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
801
|
+
return (
|
|
802
|
+
<View
|
|
803
|
+
style={[shouldApplyAndroidWorkaround ? styles.invertAndroid : undefined]}
|
|
804
|
+
testID={`message-list-item-${index}`}
|
|
805
|
+
>
|
|
806
|
+
{message.type === 'system' ? (
|
|
807
|
+
<MessageSystem
|
|
808
|
+
message={message}
|
|
809
|
+
style={[{ paddingHorizontal: screenPadding }, messageContainer]}
|
|
810
|
+
/>
|
|
811
|
+
) : wrapMessageInTheme ? (
|
|
812
|
+
<ThemeProvider mergedStyle={modifiedTheme}>
|
|
813
|
+
<View testID={`message-list-item-${index}`}>
|
|
814
|
+
{renderDateSeperator}
|
|
815
|
+
{renderMessage}
|
|
816
|
+
</View>
|
|
817
|
+
</ThemeProvider>
|
|
818
|
+
) : (
|
|
809
819
|
<View testID={`message-list-item-${index}`}>
|
|
810
820
|
{renderDateSeperator}
|
|
811
821
|
{renderMessage}
|
|
812
822
|
</View>
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
823
|
+
)}
|
|
824
|
+
{showUnreadUnderlay && <InlineUnreadIndicator />}
|
|
825
|
+
</View>
|
|
826
|
+
);
|
|
827
|
+
},
|
|
828
|
+
[
|
|
829
|
+
InlineDateSeparator,
|
|
830
|
+
InlineUnreadIndicator,
|
|
831
|
+
Message,
|
|
832
|
+
MessageSystem,
|
|
833
|
+
channel,
|
|
834
|
+
channelUnreadState?.first_unread_message_id,
|
|
835
|
+
channelUnreadState?.last_read,
|
|
836
|
+
channelUnreadState?.last_read_message_id,
|
|
837
|
+
channelUnreadState?.unread_messages,
|
|
838
|
+
client.userID,
|
|
839
|
+
goToMessage,
|
|
840
|
+
highlightedMessageId,
|
|
841
|
+
lastReceivedId,
|
|
842
|
+
messageContainer,
|
|
843
|
+
modifiedTheme,
|
|
844
|
+
myMessageTheme,
|
|
845
|
+
onThreadSelect,
|
|
846
|
+
screenPadding,
|
|
847
|
+
shouldApplyAndroidWorkaround,
|
|
848
|
+
shouldShowUnreadUnderlay,
|
|
849
|
+
threadList,
|
|
850
|
+
],
|
|
851
|
+
);
|
|
824
852
|
|
|
825
853
|
/**
|
|
826
854
|
* We are keeping full control on message pagination, and not relying on react-native for it.
|
|
@@ -845,7 +873,7 @@ const MessageListWithContext = <
|
|
|
845
873
|
* 2. Ensures that we call `loadMoreRecent`, once per content length
|
|
846
874
|
* 3. If the call to `loadMore` is in progress, we wait for it to finish to make sure scroll doesn't jump.
|
|
847
875
|
*/
|
|
848
|
-
const maybeCallOnStartReached = async () => {
|
|
876
|
+
const maybeCallOnStartReached = useStableCallback(async () => {
|
|
849
877
|
// If onStartReached has already been called for given data length, then ignore.
|
|
850
878
|
if (
|
|
851
879
|
processedMessageList?.length &&
|
|
@@ -882,14 +910,14 @@ const MessageListWithContext = <
|
|
|
882
910
|
)
|
|
883
911
|
.then(callback)
|
|
884
912
|
.catch(onError);
|
|
885
|
-
};
|
|
913
|
+
});
|
|
886
914
|
|
|
887
915
|
/**
|
|
888
916
|
* 1. Makes a call to `loadMore` function, which queries more older messages.
|
|
889
917
|
* 2. Ensures that we call `loadMore`, once per content length
|
|
890
918
|
* 3. If the call to `loadMoreRecent` is in progress, we wait for it to finish to make sure scroll doesn't jump.
|
|
891
919
|
*/
|
|
892
|
-
const maybeCallOnEndReached = async () => {
|
|
920
|
+
const maybeCallOnEndReached = useStableCallback(async () => {
|
|
893
921
|
// If onEndReached has already been called for given messageList length, then ignore.
|
|
894
922
|
if (processedMessageList?.length && onEndReachedTracker.current[processedMessageList.length]) {
|
|
895
923
|
return;
|
|
@@ -918,9 +946,9 @@ const MessageListWithContext = <
|
|
|
918
946
|
onEndReachedInPromise.current = (threadList ? loadMoreThread() : loadMore())
|
|
919
947
|
.then(callback)
|
|
920
948
|
.catch(onError);
|
|
921
|
-
};
|
|
949
|
+
});
|
|
922
950
|
|
|
923
|
-
const onUserScrollEvent: NonNullable<ScrollViewProps['onScroll']> = (event) => {
|
|
951
|
+
const onUserScrollEvent: NonNullable<ScrollViewProps['onScroll']> = useStableCallback((event) => {
|
|
924
952
|
const nativeEvent = event.nativeEvent;
|
|
925
953
|
clearTimeout(onScrollEventTimeoutRef.current);
|
|
926
954
|
const offset = nativeEvent.contentOffset.y;
|
|
@@ -941,9 +969,9 @@ const MessageListWithContext = <
|
|
|
941
969
|
if (isScrollAtEnd) {
|
|
942
970
|
maybeCallOnEndReached();
|
|
943
971
|
}
|
|
944
|
-
};
|
|
972
|
+
});
|
|
945
973
|
|
|
946
|
-
const handleScroll: ScrollViewProps['onScroll'] = (event) => {
|
|
974
|
+
const handleScroll: ScrollViewProps['onScroll'] = useStableCallback((event) => {
|
|
947
975
|
const messageListHasMessages = processedMessageList.length > 0;
|
|
948
976
|
const offset = event.nativeEvent.contentOffset.y;
|
|
949
977
|
// Show scrollToBottom button once scroll position goes beyond 150.
|
|
@@ -965,9 +993,9 @@ const MessageListWithContext = <
|
|
|
965
993
|
if (onListScroll) {
|
|
966
994
|
onListScroll(event);
|
|
967
995
|
}
|
|
968
|
-
};
|
|
996
|
+
});
|
|
969
997
|
|
|
970
|
-
const goToNewMessages = async () => {
|
|
998
|
+
const goToNewMessages = useStableCallback(async () => {
|
|
971
999
|
const isNotLatestSet = channel.state.messages !== channel.state.latestMessages;
|
|
972
1000
|
|
|
973
1001
|
if (isNotLatestSet) {
|
|
@@ -988,7 +1016,7 @@ const MessageListWithContext = <
|
|
|
988
1016
|
await markRead({
|
|
989
1017
|
updateChannelUnreadState: false,
|
|
990
1018
|
});
|
|
991
|
-
};
|
|
1019
|
+
});
|
|
992
1020
|
|
|
993
1021
|
const scrollToIndexFailedRetryCountRef = useRef<number>(0);
|
|
994
1022
|
const failScrollTimeoutId = useRef<ReturnType<typeof setTimeout>>(undefined);
|
|
@@ -1089,35 +1117,35 @@ const MessageListWithContext = <
|
|
|
1089
1117
|
threadList,
|
|
1090
1118
|
]);
|
|
1091
1119
|
|
|
1092
|
-
const dismissImagePicker = () => {
|
|
1120
|
+
const dismissImagePicker = useStableCallback(() => {
|
|
1093
1121
|
if (selectedPicker) {
|
|
1094
1122
|
setSelectedPicker(undefined);
|
|
1095
1123
|
closePicker();
|
|
1096
1124
|
}
|
|
1097
|
-
};
|
|
1125
|
+
});
|
|
1098
1126
|
|
|
1099
|
-
const onScrollBeginDrag: ScrollViewProps['onScrollBeginDrag'] = (event) => {
|
|
1127
|
+
const onScrollBeginDrag: ScrollViewProps['onScrollBeginDrag'] = useStableCallback((event) => {
|
|
1100
1128
|
!hasMoved && selectedPicker && setHasMoved(true);
|
|
1101
1129
|
onUserScrollEvent(event);
|
|
1102
|
-
};
|
|
1130
|
+
});
|
|
1103
1131
|
|
|
1104
|
-
const onScrollEndDrag: ScrollViewProps['onScrollEndDrag'] = (event) => {
|
|
1132
|
+
const onScrollEndDrag: ScrollViewProps['onScrollEndDrag'] = useStableCallback((event) => {
|
|
1105
1133
|
hasMoved && selectedPicker && setHasMoved(false);
|
|
1106
1134
|
onUserScrollEvent(event);
|
|
1107
|
-
};
|
|
1135
|
+
});
|
|
1108
1136
|
|
|
1109
|
-
const refCallback = (ref: FlatListType<MessageType<StreamChatGenerics>>) => {
|
|
1137
|
+
const refCallback = useStableCallback((ref: FlatListType<MessageType<StreamChatGenerics>>) => {
|
|
1110
1138
|
flatListRef.current = ref;
|
|
1111
1139
|
|
|
1112
1140
|
if (setFlatListRef) {
|
|
1113
1141
|
setFlatListRef(ref);
|
|
1114
1142
|
}
|
|
1115
|
-
};
|
|
1143
|
+
});
|
|
1116
1144
|
|
|
1117
|
-
const onUnreadNotificationClose = async () => {
|
|
1145
|
+
const onUnreadNotificationClose = useStableCallback(async () => {
|
|
1118
1146
|
await markRead();
|
|
1119
1147
|
setIsUnreadNotificationOpen(false);
|
|
1120
|
-
};
|
|
1148
|
+
});
|
|
1121
1149
|
|
|
1122
1150
|
const debugRef = useDebugContext();
|
|
1123
1151
|
|
|
@@ -1178,6 +1206,25 @@ const MessageListWithContext = <
|
|
|
1178
1206
|
additionalFlatListPropsExcludingStyle = rest;
|
|
1179
1207
|
}
|
|
1180
1208
|
|
|
1209
|
+
const flatListStyle = useMemo(
|
|
1210
|
+
() => [
|
|
1211
|
+
styles.listContainer,
|
|
1212
|
+
listContainer,
|
|
1213
|
+
additionalFlatListProps?.style,
|
|
1214
|
+
shouldApplyAndroidWorkaround ? styles.invertAndroid : undefined,
|
|
1215
|
+
],
|
|
1216
|
+
[additionalFlatListProps?.style, listContainer, shouldApplyAndroidWorkaround],
|
|
1217
|
+
);
|
|
1218
|
+
|
|
1219
|
+
const flatListContentContainerStyle = useMemo(
|
|
1220
|
+
() => [
|
|
1221
|
+
styles.contentContainer,
|
|
1222
|
+
additionalFlatListProps?.contentContainerStyle,
|
|
1223
|
+
contentContainer,
|
|
1224
|
+
],
|
|
1225
|
+
[additionalFlatListProps?.contentContainerStyle, contentContainer],
|
|
1226
|
+
);
|
|
1227
|
+
|
|
1181
1228
|
if (!FlatList) {
|
|
1182
1229
|
return null;
|
|
1183
1230
|
}
|
|
@@ -1202,11 +1249,7 @@ const MessageListWithContext = <
|
|
|
1202
1249
|
</View>
|
|
1203
1250
|
) : (
|
|
1204
1251
|
<FlatList
|
|
1205
|
-
contentContainerStyle={
|
|
1206
|
-
styles.contentContainer,
|
|
1207
|
-
additionalFlatListProps?.contentContainerStyle,
|
|
1208
|
-
contentContainer,
|
|
1209
|
-
]}
|
|
1252
|
+
contentContainerStyle={flatListContentContainerStyle}
|
|
1210
1253
|
/** Disables the MessageList UI. Which means, message actions, reactions won't work. */
|
|
1211
1254
|
data={processedMessageList}
|
|
1212
1255
|
extraData={disabled}
|
|
@@ -1222,10 +1265,7 @@ const MessageListWithContext = <
|
|
|
1222
1265
|
minIndexForVisible = 1 means that beyond the item at index 1 we will not change the position on list updates,
|
|
1223
1266
|
however it is not used when autoscrollToTopThreshold = 10.
|
|
1224
1267
|
*/
|
|
1225
|
-
maintainVisibleContentPosition={
|
|
1226
|
-
autoscrollToTopThreshold: autoscrollToRecent ? 10 : undefined,
|
|
1227
|
-
minIndexForVisible: 1,
|
|
1228
|
-
}}
|
|
1268
|
+
maintainVisibleContentPosition={maintainVisibleContentPosition}
|
|
1229
1269
|
maxToRenderPerBatch={30}
|
|
1230
1270
|
onMomentumScrollEnd={onUserScrollEvent}
|
|
1231
1271
|
onScroll={handleScroll}
|
|
@@ -1238,12 +1278,7 @@ const MessageListWithContext = <
|
|
|
1238
1278
|
renderItem={renderItem}
|
|
1239
1279
|
scrollEnabled={overlay === 'none'}
|
|
1240
1280
|
showsVerticalScrollIndicator={!shouldApplyAndroidWorkaround}
|
|
1241
|
-
style={
|
|
1242
|
-
styles.listContainer,
|
|
1243
|
-
listContainer,
|
|
1244
|
-
additionalFlatListProps?.style,
|
|
1245
|
-
shouldApplyAndroidWorkaround ? styles.invertAndroid : undefined,
|
|
1246
|
-
]}
|
|
1281
|
+
style={flatListStyle}
|
|
1247
1282
|
testID='message-flat-list'
|
|
1248
1283
|
viewabilityConfig={flatListViewabilityConfig}
|
|
1249
1284
|
{...additionalFlatListPropsExcludingStyle}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
|
|
1
3
|
import type { ChannelState, MessageResponse } from 'stream-chat';
|
|
2
4
|
|
|
3
5
|
import { useLastReadData } from './useLastReadData';
|
|
@@ -44,6 +46,29 @@ export const isMessageWithStylesReadByAndDateSeparator = <
|
|
|
44
46
|
): message is MessagesWithStylesReadByAndDateSeparator<StreamChatGenerics> =>
|
|
45
47
|
(message as MessagesWithStylesReadByAndDateSeparator<StreamChatGenerics>).readBy !== undefined;
|
|
46
48
|
|
|
49
|
+
export const shouldIncludeMessageInList = <
|
|
50
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
51
|
+
>(
|
|
52
|
+
message: MessageType<StreamChatGenerics>,
|
|
53
|
+
options: { deletedMessagesVisibilityType?: DeletedMessagesVisibilityType; userId?: string },
|
|
54
|
+
) => {
|
|
55
|
+
const { deletedMessagesVisibilityType, userId } = options;
|
|
56
|
+
const isMessageTypeDeleted = message.type === 'deleted';
|
|
57
|
+
switch (deletedMessagesVisibilityType) {
|
|
58
|
+
case 'sender':
|
|
59
|
+
return !isMessageTypeDeleted || message.user?.id === userId;
|
|
60
|
+
|
|
61
|
+
case 'receiver':
|
|
62
|
+
return !isMessageTypeDeleted || message.user?.id !== userId;
|
|
63
|
+
|
|
64
|
+
case 'never':
|
|
65
|
+
return !isMessageTypeDeleted;
|
|
66
|
+
|
|
67
|
+
default:
|
|
68
|
+
return !!message;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
47
72
|
export const useMessageList = <
|
|
48
73
|
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
49
74
|
>(
|
|
@@ -63,51 +88,57 @@ export const useMessageList = <
|
|
|
63
88
|
? undefined
|
|
64
89
|
: read;
|
|
65
90
|
|
|
66
|
-
const dateSeparators = getDateSeparators<StreamChatGenerics>({
|
|
67
|
-
deletedMessagesVisibilityType,
|
|
68
|
-
hideDateSeparators,
|
|
69
|
-
messages: messageList,
|
|
70
|
-
userId: client.userID,
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
const messageGroupStyles = getMessagesGroupStyles<StreamChatGenerics>({
|
|
74
|
-
dateSeparators,
|
|
75
|
-
hideDateSeparators,
|
|
76
|
-
maxTimeBetweenGroupedMessages,
|
|
77
|
-
messages: messageList,
|
|
78
|
-
noGroupByUser,
|
|
79
|
-
userId: client.userID,
|
|
80
|
-
});
|
|
81
|
-
|
|
82
91
|
const readData = useLastReadData({
|
|
83
92
|
messages: messageList,
|
|
84
93
|
read: readList,
|
|
85
94
|
userID: client.userID,
|
|
86
95
|
});
|
|
87
96
|
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
const processedMessageList = useMemo<MessageType<StreamChatGenerics>[]>(() => {
|
|
98
|
+
const dateSeparators = getDateSeparators({
|
|
99
|
+
deletedMessagesVisibilityType,
|
|
100
|
+
hideDateSeparators,
|
|
101
|
+
messages: messageList,
|
|
102
|
+
userId: client.userID,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const messageGroupStyles = getMessagesGroupStyles({
|
|
106
|
+
dateSeparators,
|
|
107
|
+
hideDateSeparators,
|
|
108
|
+
maxTimeBetweenGroupedMessages,
|
|
109
|
+
messages: messageList,
|
|
110
|
+
noGroupByUser,
|
|
111
|
+
userId: client.userID,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const newMessageList = [];
|
|
115
|
+
for (const message of messageList) {
|
|
116
|
+
if (
|
|
117
|
+
shouldIncludeMessageInList(message, {
|
|
118
|
+
deletedMessagesVisibilityType,
|
|
119
|
+
userId: client.userID,
|
|
120
|
+
})
|
|
121
|
+
) {
|
|
122
|
+
const messageId = message.id;
|
|
123
|
+
newMessageList.unshift({
|
|
124
|
+
...message,
|
|
125
|
+
dateSeparator: dateSeparators[messageId] || undefined,
|
|
126
|
+
groupStyles: messageGroupStyles[messageId] || ['single'],
|
|
127
|
+
readBy: messageId ? readData[messageId] || false : false,
|
|
128
|
+
});
|
|
99
129
|
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
130
|
+
}
|
|
131
|
+
return newMessageList;
|
|
132
|
+
}, [
|
|
133
|
+
client.userID,
|
|
134
|
+
deletedMessagesVisibilityType,
|
|
135
|
+
getMessagesGroupStyles,
|
|
136
|
+
hideDateSeparators,
|
|
137
|
+
maxTimeBetweenGroupedMessages,
|
|
138
|
+
messageList,
|
|
139
|
+
noGroupByUser,
|
|
140
|
+
readData,
|
|
141
|
+
]);
|
|
111
142
|
|
|
112
143
|
return {
|
|
113
144
|
/** Messages enriched with dates/readby/groups and also reversed in order */
|