@@ -222,6 +222,11 @@ type MessageListPropsWithContext = Pick<
222222 * ```
223223 */
224224 setFlatListRef ?: ( ref : FlatListType < LocalMessage > | null ) => void ;
225+ /**
226+ * If true, the message list will be used in a live-streaming scenario.
227+ * This flag is used to make sure that the auto scroll behaves well, if multiple messages are received.
228+ */
229+ isLiveStreaming ?: boolean ;
225230 } ;
226231
227232/**
@@ -256,6 +261,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
256261 InlineUnreadIndicator,
257262 inverted = true ,
258263 isListActive = false ,
264+ isLiveStreaming = false ,
259265 legacyImageViewerSwipeBehaviour,
260266 loadChannelAroundMessage,
261267 loading,
@@ -336,12 +342,17 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
336342
337343 const minIndexForVisible = Math . min ( 1 , processedMessageList . length ) ;
338344
345+ const autoscrollToTopThreshold = useMemo (
346+ ( ) => ( isLiveStreaming ? 64 : autoscrollToRecent ? 10 : undefined ) ,
347+ [ autoscrollToRecent , isLiveStreaming ] ,
348+ ) ;
349+
339350 const maintainVisibleContentPosition = useMemo (
340351 ( ) => ( {
341- autoscrollToTopThreshold : 64 ,
352+ autoscrollToTopThreshold,
342353 minIndexForVisible,
343354 } ) ,
344- [ minIndexForVisible ] ,
355+ [ autoscrollToTopThreshold , minIndexForVisible ] ,
345356 ) ;
346357
347358 /**
@@ -652,7 +663,11 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
652663 latestNonCurrentMessageBeforeUpdate ?. id === latestCurrentMessageAfterUpdate . id ;
653664 // if didMergeMessageSetsWithNoUpdates=false, we got new messages
654665 // so we should scroll to bottom if we are near the bottom already
655- setAutoscrollToRecent ( ! didMergeMessageSetsWithNoUpdates ) ;
666+ const shouldForceScrollToRecent =
667+ ! didMergeMessageSetsWithNoUpdates ||
668+ processedMessageList . length - messageListLengthBeforeUpdate . current > 0 ;
669+
670+ setAutoscrollToRecent ( shouldForceScrollToRecent ) ;
656671
657672 if ( ! didMergeMessageSetsWithNoUpdates ) {
658673 const shouldScrollToRecentOnNewOwnMessage = shouldScrollToRecentOnNewOwnMessageRef . current ( ) ;
@@ -667,8 +682,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
667682 } , WAIT_FOR_SCROLL_TIMEOUT ) ; // flatlist might take a bit to update, so a small delay is needed
668683 }
669684 }
670- // eslint-disable-next-line react-hooks/exhaustive-deps
671- } , [ channel , processedMessageList , threadList ] ) ;
685+ } , [ channel , threadList , processedMessageList , shouldScrollToRecentOnNewOwnMessageRef ] ) ;
672686
673687 const goToMessage = useStableCallback ( async ( messageId : string ) => {
674688 const indexOfParentInMessageList = processedMessageList . findIndex (
@@ -1218,10 +1232,10 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
12181232 onViewableItemsChanged = { stableOnViewableItemsChanged }
12191233 ref = { refCallback }
12201234 renderItem = { renderItem }
1221- scrollEventThrottle = { 16 }
1235+ scrollEventThrottle = { isLiveStreaming ? 16 : undefined }
12221236 showsVerticalScrollIndicator = { false }
12231237 // @ts -expect-error react-native internal
1224- strictMode = { true }
1238+ strictMode = { isLiveStreaming ? true : false }
12251239 style = { flatListStyle }
12261240 testID = 'message-flat-list'
12271241 viewabilityConfig = { flatListViewabilityConfig }
0 commit comments