@@ -222,6 +222,15 @@ type MessageListPropsWithContext = Pick<
222
222
* ```
223
223
*/
224
224
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
+ * This flag is experimental and is subject to change. Please test thoroughly before using it.
230
+ *
231
+ * @experimental
232
+ */
233
+ isLiveStreaming ?: boolean ;
225
234
} ;
226
235
227
236
/**
@@ -256,6 +265,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
256
265
InlineUnreadIndicator,
257
266
inverted = true ,
258
267
isListActive = false ,
268
+ isLiveStreaming = false ,
259
269
legacyImageViewerSwipeBehaviour,
260
270
loadChannelAroundMessage,
261
271
loading,
@@ -313,6 +323,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
313
323
*/
314
324
const { dateSeparatorsRef, messageGroupStylesRef, processedMessageList, rawMessageList } =
315
325
useMessageList ( {
326
+ isLiveStreaming,
316
327
noGroupByUser,
317
328
threadList,
318
329
} ) ;
@@ -336,12 +347,17 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
336
347
337
348
const minIndexForVisible = Math . min ( 1 , processedMessageList . length ) ;
338
349
350
+ const autoscrollToTopThreshold = useMemo (
351
+ ( ) => ( isLiveStreaming ? 64 : autoscrollToRecent ? 10 : undefined ) ,
352
+ [ autoscrollToRecent , isLiveStreaming ] ,
353
+ ) ;
354
+
339
355
const maintainVisibleContentPosition = useMemo (
340
356
( ) => ( {
341
- autoscrollToTopThreshold : autoscrollToRecent ? 10 : undefined ,
357
+ autoscrollToTopThreshold,
342
358
minIndexForVisible,
343
359
} ) ,
344
- [ autoscrollToRecent , minIndexForVisible ] ,
360
+ [ autoscrollToTopThreshold , minIndexForVisible ] ,
345
361
) ;
346
362
347
363
/**
@@ -652,7 +668,11 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
652
668
latestNonCurrentMessageBeforeUpdate ?. id === latestCurrentMessageAfterUpdate . id ;
653
669
// if didMergeMessageSetsWithNoUpdates=false, we got new messages
654
670
// so we should scroll to bottom if we are near the bottom already
655
- setAutoscrollToRecent ( ! didMergeMessageSetsWithNoUpdates ) ;
671
+ const shouldForceScrollToRecent =
672
+ ! didMergeMessageSetsWithNoUpdates ||
673
+ processedMessageList . length - messageListLengthBeforeUpdate . current > 0 ;
674
+
675
+ setAutoscrollToRecent ( shouldForceScrollToRecent ) ;
656
676
657
677
if ( ! didMergeMessageSetsWithNoUpdates ) {
658
678
const shouldScrollToRecentOnNewOwnMessage = shouldScrollToRecentOnNewOwnMessageRef . current ( ) ;
@@ -667,8 +687,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
667
687
} , WAIT_FOR_SCROLL_TIMEOUT ) ; // flatlist might take a bit to update, so a small delay is needed
668
688
}
669
689
}
670
- // eslint-disable-next-line react-hooks/exhaustive-deps
671
- } , [ channel , processedMessageList , threadList ] ) ;
690
+ } , [ channel , threadList , processedMessageList , shouldScrollToRecentOnNewOwnMessageRef ] ) ;
672
691
673
692
const goToMessage = useStableCallback ( async ( messageId : string ) => {
674
693
const indexOfParentInMessageList = processedMessageList . findIndex (
@@ -1218,7 +1237,10 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
1218
1237
onViewableItemsChanged = { stableOnViewableItemsChanged }
1219
1238
ref = { refCallback }
1220
1239
renderItem = { renderItem }
1240
+ scrollEventThrottle = { isLiveStreaming ? 16 : undefined }
1221
1241
showsVerticalScrollIndicator = { false }
1242
+ // @ts -expect-error react-native internal
1243
+ strictMode = { isLiveStreaming }
1222
1244
style = { flatListStyle }
1223
1245
testID = 'message-flat-list'
1224
1246
viewabilityConfig = { flatListViewabilityConfig }
0 commit comments