RoomList: introduce incremental loading to improve performances.

This commit is contained in:
ganfra 2023-11-29 11:53:15 +01:00
parent 656fcbd5e4
commit fda114d648
7 changed files with 99 additions and 56 deletions

View file

@ -16,6 +16,12 @@
package io.element.android.libraries.matrix.api.roomlist
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
/**
* RoomList with dynamic filtering and loading.
* This is useful for large lists of rooms.
@ -23,17 +29,17 @@ package io.element.android.libraries.matrix.api.roomlist
*/
interface DynamicRoomList : RoomList {
companion object {
const val DEFAULT_PAGE_SIZE = 20
const val DEFAULT_PAGES_TO_LOAD = 10
}
sealed interface Filter {
/**
* No filter applied.
*/
data object All : Filter
/**
* Filter only the left rooms.
*/
data object AllNonLeft : Filter
/**
* Filter all rooms.
*/
@ -45,6 +51,10 @@ interface DynamicRoomList : RoomList {
data class NormalizedMatchRoomName(val pattern: String) : Filter
}
val currentFilter: StateFlow<Filter>
val loadedPages: StateFlow<Int>
val pageSize: Int
/**
* Load more rooms into the list if possible.
*/
@ -61,3 +71,29 @@ interface DynamicRoomList : RoomList {
*/
suspend fun updateFilter(filter: Filter)
}
/**
* Offers a way to load all the rooms incrementally.
* It will load more room until all are loaded.
* If total number of rooms increase, it will load more pages if needed.
* The number of rooms is independent of the filter.
*/
fun DynamicRoomList.loadAllIncrementally(coroutineScope: CoroutineScope) {
combine(
loadedPages,
loadingState,
) { loadedPages, loadingState ->
loadedPages to loadingState
}
.onEach { (loadedPages, loadingState) ->
when (loadingState) {
is RoomList.LoadingState.Loaded -> {
if (pageSize * loadedPages < loadingState.numberOfRooms) {
loadMore()
}
}
RoomList.LoadingState.NotLoaded -> Unit
}
}
.launchIn(coroutineScope)
}

View file

@ -38,10 +38,10 @@ interface RoomListService {
}
/**
* returns a [RoomList] object of all rooms we want to display.
* returns a [DynamicRoomList] object of all rooms we want to display.
* This will exclude some rooms like the invites, or spaces.
*/
val allRooms: RoomList
val allRooms: DynamicRoomList
/**
* returns a [RoomList] object of all invites.