From 6463af83a32b1e26bad60ac946120e8f1a26da4b Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 1 Oct 2024 23:01:40 +0200 Subject: [PATCH] timeline : do not call focusOnLive too soon #2 --- .../impl/timeline/TimelineController.kt | 5 ++-- .../impl/timeline/TimelinePresenter.kt | 24 +++++++++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineController.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineController.kt index bb64e58212..7354f2bedc 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineController.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineController.kt @@ -57,8 +57,9 @@ class TimelineController @Inject constructor( return detachedTimeline.map { !it.isPresent } } - fun currentPaginationStatus(direction: Timeline.PaginationDirection): Timeline.PaginationStatus { - return currentTimelineFlow.value.paginationStatus(direction).value + @OptIn(ExperimentalCoroutinesApi::class) + fun paginationStatus(direction: Timeline.PaginationDirection): Flow { + return currentTimelineFlow.flatMapLatest { timeline -> timeline.paginationStatus(direction)} } suspend fun invokeOnCurrentTimeline(block: suspend (Timeline.() -> Any)) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt index 2989701c9f..ad1ce919fe 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt @@ -53,6 +53,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -130,6 +131,8 @@ class TimelinePresenter @AssistedInject constructor( val renderReadReceipts by sessionPreferencesStore.isRenderReadReceiptsEnabled().collectAsState(initial = true) val isLive by timelineController.isLive().collectAsState(initial = true) + var shouldFocusOnLive by rememberSaveable { mutableStateOf(false) } + fun handleEvents(event: TimelineEvents) { when (event) { is TimelineEvents.LoadMore -> { @@ -142,7 +145,7 @@ class TimelinePresenter @AssistedInject constructor( if (event.firstIndex == 0) { newEventState.value = NewEventState.None } - println("## sendReadReceiptIfNeeded firstVisibleIndex: ${event.firstIndex}") + shouldFocusOnLive = false appScope.sendReadReceiptIfNeeded( firstVisibleIndex = event.firstIndex, timelineItems = timelineItems, @@ -151,12 +154,7 @@ class TimelinePresenter @AssistedInject constructor( ) } else { newEventState.value = NewEventState.None - if (event.firstIndex == 0) { - val forwardPaginationStatus = timelineController.currentPaginationStatus(Timeline.PaginationDirection.FORWARDS) - if (!forwardPaginationStatus.hasMoreToLoad) { - timelineController.focusOnLive() - } - } + shouldFocusOnLive = event.firstIndex == 0 } } is TimelineEvents.SelectPollAnswer -> appScope.launch { @@ -193,6 +191,18 @@ class TimelinePresenter @AssistedInject constructor( } } + val hasMoreToLoadForward by remember { + timelineController + .paginationStatus(Timeline.PaginationDirection.FORWARDS) + .map { it.hasMoreToLoad } + }.collectAsState(false) + + LaunchedEffect(shouldFocusOnLive, hasMoreToLoadForward) { + if (shouldFocusOnLive && !hasMoreToLoadForward) { + timelineController.focusOnLive() + } + } + LaunchedEffect(focusRequestState) { when (val currentFocusRequestState = focusRequestState) { is FocusRequestState.Requested -> {