From 5e6bcbd7ac9c95565ec89f8a78ecd02c29ea7855 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 17 Jul 2024 15:49:11 +0200 Subject: [PATCH] Performance : do not trigger back pagination when opening room. --- .../matrix/impl/timeline/RustTimeline.kt | 31 ++++++++++++++----- .../impl/timeline/TimelineItemsSubscriber.kt | 8 ++--- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt index fb42f27f62..fe2f01925d 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt @@ -81,7 +81,6 @@ import timber.log.Timber import uniffi.matrix_sdk_ui.LiveBackPaginationStatus import java.io.File import java.util.Date -import java.util.concurrent.atomic.AtomicBoolean import org.matrix.rustcomponents.sdk.Timeline as InnerTimeline private const val PAGINATION_SIZE = 50 @@ -99,7 +98,7 @@ class RustTimeline( onNewSyncedEvent: () -> Unit, ) : Timeline { private val initLatch = CompletableDeferred() - private val isInit = AtomicBoolean(false) + private val isInit = MutableStateFlow(false) private val _timelineItems: MutableStateFlow> = MutableStateFlow(emptyList()) @@ -208,7 +207,7 @@ class RustTimeline( } private fun canPaginate(direction: Timeline.PaginationDirection): Boolean { - if (!isInit.get()) return false + if (!isInit.value) return false return when (direction) { Timeline.PaginationDirection.BACKWARDS -> backPaginationStatus.value.canPaginate Timeline.PaginationDirection.FORWARDS -> forwardPaginationStatus.value.canPaginate @@ -226,20 +225,25 @@ class RustTimeline( _timelineItems, backPaginationStatus.map { it.hasMoreToLoad }.distinctUntilChanged(), forwardPaginationStatus.map { it.hasMoreToLoad }.distinctUntilChanged(), - ) { timelineItems, hasMoreToLoadBackward, hasMoreToLoadForward -> + isInit, + ) { timelineItems, hasMoreToLoadBackward, hasMoreToLoadForward, isInit -> withContext(dispatcher) { timelineItems - .let { items -> encryptedHistoryPostProcessor.process(items) } - .let { items -> + .process { items -> encryptedHistoryPostProcessor.process(items) } + .process { items -> roomBeginningPostProcessor.process( items = items, isDm = matrixRoom.isDm, hasMoreToLoadBackwards = hasMoreToLoadBackward ) } - .let { items -> loadingIndicatorsPostProcessor.process(items, hasMoreToLoadBackward, hasMoreToLoadForward) } + .process(predicate = isInit) { items -> + loadingIndicatorsPostProcessor.process(items, hasMoreToLoadBackward, hasMoreToLoadForward) + } // Keep lastForwardIndicatorsPostProcessor last - .let { items -> lastForwardIndicatorsPostProcessor.process(items) } + .process(predicate = isInit) { items -> + lastForwardIndicatorsPostProcessor.process(items) + } } }.onStart { timelineItemsSubscriber.subscribeIfNeeded() @@ -545,3 +549,14 @@ class RustTimeline( } } } + +private suspend fun List.process( + predicate: Boolean = true, + processor: suspend (List) -> List +): List { + return if (predicate) { + processor(this) + } else { + this + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/TimelineItemsSubscriber.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/TimelineItemsSubscriber.kt index a4086c2810..d5454ff254 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/TimelineItemsSubscriber.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/TimelineItemsSubscriber.kt @@ -23,6 +23,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.ensureActive +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.sync.Mutex @@ -32,7 +33,6 @@ import org.matrix.rustcomponents.sdk.TimelineChange import org.matrix.rustcomponents.sdk.TimelineDiff import org.matrix.rustcomponents.sdk.TimelineItem import uniffi.matrix_sdk_ui.EventItemOrigin -import java.util.concurrent.atomic.AtomicBoolean private const val INITIAL_MAX_SIZE = 50 @@ -47,7 +47,7 @@ internal class TimelineItemsSubscriber( private val timeline: Timeline, private val timelineDiffProcessor: MatrixTimelineDiffProcessor, private val initLatch: CompletableDeferred, - private val isInit: AtomicBoolean, + private val isInit: MutableStateFlow, private val onNewSyncedEvent: () -> Unit, ) { private var subscriptionCount = 0 @@ -94,13 +94,13 @@ internal class TimelineItemsSubscriber( ensureActive() timelineDiffProcessor.postItems(it) } - isInit.set(true) + isInit.value = true initLatch.complete(Unit) } private suspend fun postDiffs(diffs: List) { val diffsToProcess = diffs.toMutableList() - if (!isInit.get()) { + if (!isInit.value) { val resetDiff = diffsToProcess.firstOrNull { it.change() == TimelineChange.RESET } if (resetDiff != null) { // Keep using the postItems logic so we can post the timelineItems asap.