From d3d314d9f995c9b517672e6748bd835fc4ce7a41 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Fri, 30 Jun 2023 20:54:29 +0200 Subject: [PATCH] Merge the read receipts code with `TimelineScrollHelper` (#736) --- .../messages/impl/timeline/TimelineView.kt | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt index 74bb593f11..c355431d2c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt @@ -77,6 +77,10 @@ fun TimelineView( state.eventSink(TimelineEvents.LoadMore) } + fun onScrollFinishedAt(firstVisibleIndex: Int) { + state.eventSink(TimelineEvents.OnScrollFinished(firstVisibleIndex)) + } + val lazyListState = rememberLazyListState() fun inReplyToClicked(eventId: EventId) { @@ -121,7 +125,8 @@ fun TimelineView( TimelineScrollHelper( lazyListState = lazyListState, - timelineItems = state.timelineItems + timelineItems = state.timelineItems, + onScrollFinishedAt = ::onScrollFinishedAt, ) } } @@ -219,21 +224,29 @@ fun TimelineItemRow( internal fun BoxScope.TimelineScrollHelper( lazyListState: LazyListState, timelineItems: ImmutableList, + onScrollFinishedAt: (Int) -> Unit = {}, ) { val coroutineScope = rememberCoroutineScope() val firstVisibleItemIndex by remember { derivedStateOf { lazyListState.firstVisibleItemIndex } } + val isScrollFinished by remember { derivedStateOf { !lazyListState.isScrollInProgress } } + val shouldAutoScrollToBottom by remember { derivedStateOf { lazyListState.firstVisibleItemIndex < 2 } } - // Auto-scroll when new timeline items appear - LaunchedEffect(timelineItems, firstVisibleItemIndex) { - if (!lazyListState.isScrollInProgress && - firstVisibleItemIndex < 2 - ) coroutineScope.launch { - lazyListState.animateScrollToItem(0) + LaunchedEffect(timelineItems, firstVisibleItemIndex, isScrollFinished) { + if (!isScrollFinished) return@LaunchedEffect + + // Notify the parent composable about the first visible item index when scrolling finishes + onScrollFinishedAt(firstVisibleItemIndex) + + // Auto-scroll when new timeline items appear + if (shouldAutoScrollToBottom) { + coroutineScope.launch { + lazyListState.animateScrollToItem(0) + } } } // Jump to bottom button - if (firstVisibleItemIndex > 2) { + if (!shouldAutoScrollToBottom) { FloatingActionButton( onClick = { coroutineScope.launch {