Merge pull request #863 from vector-im/feature/fga/timeline_pagination

Feature/fga/timeline pagination
This commit is contained in:
ganfra 2023-07-13 11:58:10 +02:00 committed by GitHub
commit 732a4eb5fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 61 additions and 30 deletions

View file

@ -31,14 +31,12 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MessageEventType
import io.element.android.libraries.matrix.api.timeline.MatrixTimeline
import io.element.android.libraries.matrix.ui.room.canSendEventAsState
import kotlinx.collections.immutable.ImmutableList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
private const val backPaginationEventLimit = 20
@ -69,7 +67,7 @@ class TimelinePresenter @Inject constructor(
fun handleEvents(event: TimelineEvents) {
when (event) {
TimelineEvents.LoadMore -> localCoroutineScope.loadMore(paginationState)
TimelineEvents.LoadMore -> localCoroutineScope.paginateBackwards()
is TimelineEvents.SetHighlightedEvent -> highlightedEventId.value = event.eventId
is TimelineEvents.OnScrollFinished -> {
// Get last valid EventId seen by the user, as the first index might refer to a Virtual item
@ -89,7 +87,7 @@ class TimelinePresenter @Inject constructor(
.onEach(timelineItemsFactory::replaceWith)
.onEach { timelineItems ->
if (timelineItems.isEmpty()) {
loadMore(paginationState)
paginateBackwards()
}
}
.launchIn(this)
@ -113,12 +111,8 @@ class TimelinePresenter @Inject constructor(
return null
}
private fun CoroutineScope.loadMore(paginationState: MatrixTimeline.PaginationState) = launch {
if (paginationState.canBackPaginate && !paginationState.isBackPaginating) {
timeline.paginateBackwards(backPaginationEventLimit, backPaginationPageSize)
} else {
Timber.v("Can't back paginate as paginationState = $paginationState")
}
private fun CoroutineScope.paginateBackwards() = launch {
timeline.paginateBackwards(backPaginationEventLimit, backPaginationPageSize)
}
private fun CoroutineScope.sendReadReceipt(eventId: EventId) = launch {

View file

@ -41,7 +41,7 @@ import kotlin.random.Random
fun aTimelineState(timelineItems: ImmutableList<TimelineItem> = persistentListOf()) = TimelineState(
timelineItems = timelineItems,
paginationState = MatrixTimeline.PaginationState(isBackPaginating = false, canBackPaginate = true),
paginationState = MatrixTimeline.PaginationState(isBackPaginating = false, hasMoreToLoadBackwards = true),
highlightedEventId = null,
canReply = true,
eventSink = {}

View file

@ -134,7 +134,7 @@ fun TimelineView(
onSwipeToReply = onSwipeToReply,
)
}
if (state.paginationState.canBackPaginate) {
if (state.paginationState.hasMoreToLoadBackwards) {
// Do not use key parameter to avoid wrong positioning
item(contentType = "TimelineLoadingMoreIndicator") {
TimelineLoadingMoreIndicator()

View file

@ -59,14 +59,14 @@ class TimelinePresenterTest {
presenter.present()
}.test {
val initialState = awaitItem()
assertThat(initialState.paginationState.canBackPaginate).isTrue()
assertThat(initialState.paginationState.hasMoreToLoadBackwards).isTrue()
assertThat(initialState.paginationState.isBackPaginating).isFalse()
initialState.eventSink.invoke(TimelineEvents.LoadMore)
val inPaginationState = awaitItem()
assertThat(inPaginationState.paginationState.isBackPaginating).isTrue()
assertThat(inPaginationState.paginationState.canBackPaginate).isTrue()
assertThat(inPaginationState.paginationState.hasMoreToLoadBackwards).isTrue()
val postPaginationState = awaitItem()
assertThat(postPaginationState.paginationState.canBackPaginate).isTrue()
assertThat(postPaginationState.paginationState.hasMoreToLoadBackwards).isTrue()
assertThat(postPaginationState.paginationState.isBackPaginating).isFalse()
}
}