RoomListFilters : use kotlin filtering as rust one is slower and has more chance to bust the room list cache.
This commit is contained in:
parent
593a94b994
commit
bd87e99df1
13 changed files with 278 additions and 112 deletions
|
|
@ -23,11 +23,13 @@ import io.element.android.libraries.matrix.api.roomlist.RoomSummary
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.getAndUpdate
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind
|
||||
import org.matrix.rustcomponents.sdk.RoomListLoadingState
|
||||
import org.matrix.rustcomponents.sdk.RoomListService
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
|
@ -50,6 +52,7 @@ internal class RoomListFactory(
|
|||
innerProvider: suspend () -> InnerRoomList
|
||||
): DynamicRoomList {
|
||||
val loadingStateFlow: MutableStateFlow<RoomList.LoadingState> = MutableStateFlow(RoomList.LoadingState.NotLoaded)
|
||||
val filteredSummariesFlow = MutableSharedFlow<List<RoomSummary>>(replay = 1, extraBufferCapacity = 1)
|
||||
val summariesFlow = MutableSharedFlow<List<RoomSummary>>(replay = 1, extraBufferCapacity = 1)
|
||||
val processor = RoomSummaryListProcessor(summariesFlow, innerRoomListService, coroutineContext, roomSummaryDetailsFactory)
|
||||
// Makes sure we don't miss any events
|
||||
|
|
@ -63,8 +66,8 @@ internal class RoomListFactory(
|
|||
innerRoomList?.let { innerRoomList ->
|
||||
innerRoomList.entriesFlow(
|
||||
pageSize = pageSize,
|
||||
initialFilterKind = initialFilter.toRustFilter(),
|
||||
roomListDynamicEvents = dynamicEvents
|
||||
roomListDynamicEvents = dynamicEvents,
|
||||
initialFilterKind = RoomListEntriesDynamicFilterKind.NonLeft
|
||||
).onEach { update ->
|
||||
processor.postUpdate(update)
|
||||
}.launchIn(this)
|
||||
|
|
@ -75,12 +78,21 @@ internal class RoomListFactory(
|
|||
loadingStateFlow.value = it
|
||||
}
|
||||
.launchIn(this)
|
||||
|
||||
combine(
|
||||
currentFilter,
|
||||
summariesFlow
|
||||
) { filter, summaries ->
|
||||
summaries.filter(filter)
|
||||
}.onEach {
|
||||
filteredSummariesFlow.emit(it)
|
||||
}.launchIn(this)
|
||||
}
|
||||
}.invokeOnCompletion {
|
||||
innerRoomList?.destroy()
|
||||
}
|
||||
return RustDynamicRoomList(
|
||||
summaries = summariesFlow,
|
||||
summaries = filteredSummariesFlow,
|
||||
loadingState = loadingStateFlow,
|
||||
currentFilter = currentFilter,
|
||||
loadedPages = loadedPages,
|
||||
|
|
@ -106,8 +118,6 @@ private class RustDynamicRoomList(
|
|||
|
||||
override suspend fun updateFilter(filter: RoomListFilter) {
|
||||
currentFilter.emit(filter)
|
||||
val filterEvent = RoomListDynamicEvents.SetFilter(filter.toRustFilter())
|
||||
dynamicEvents.emit(filterEvent)
|
||||
}
|
||||
|
||||
override suspend fun loadMore() {
|
||||
|
|
|
|||
|
|
@ -17,20 +17,41 @@
|
|||
package io.element.android.libraries.matrix.impl.roomlist
|
||||
|
||||
import io.element.android.libraries.matrix.api.roomlist.RoomListFilter
|
||||
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind
|
||||
import org.matrix.rustcomponents.sdk.RoomListFilterCategory
|
||||
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
|
||||
|
||||
fun RoomListFilter.toRustFilter(): RoomListEntriesDynamicFilterKind {
|
||||
return when (this) {
|
||||
is RoomListFilter.All -> RoomListEntriesDynamicFilterKind.All(filters.map { it.toRustFilter() })
|
||||
is RoomListFilter.Any -> RoomListEntriesDynamicFilterKind.Any(filters.map { it.toRustFilter() })
|
||||
RoomListFilter.Category.Group -> RoomListEntriesDynamicFilterKind.Category(RoomListFilterCategory.GROUP)
|
||||
RoomListFilter.Category.People -> RoomListEntriesDynamicFilterKind.Category(RoomListFilterCategory.PEOPLE)
|
||||
is RoomListFilter.FuzzyMatchRoomName -> RoomListEntriesDynamicFilterKind.FuzzyMatchRoomName(pattern)
|
||||
RoomListFilter.NonLeft -> RoomListEntriesDynamicFilterKind.NonLeft
|
||||
RoomListFilter.None -> RoomListEntriesDynamicFilterKind.None
|
||||
is RoomListFilter.NormalizedMatchRoomName -> RoomListEntriesDynamicFilterKind.NormalizedMatchRoomName(pattern)
|
||||
RoomListFilter.Unread -> RoomListEntriesDynamicFilterKind.Unread
|
||||
RoomListFilter.Favorite -> RoomListEntriesDynamicFilterKind.Favourite
|
||||
val RoomListFilter.predicate
|
||||
get() = when (this) {
|
||||
is RoomListFilter.All -> { _: RoomSummary -> true }
|
||||
is RoomListFilter.Any -> { _: RoomSummary -> true }
|
||||
RoomListFilter.None -> { _: RoomSummary -> false }
|
||||
RoomListFilter.Category.Group -> { roomSummary: RoomSummary ->
|
||||
roomSummary is RoomSummary.Filled && !roomSummary.details.isDirect
|
||||
}
|
||||
RoomListFilter.Category.People -> { roomSummary: RoomSummary ->
|
||||
roomSummary is RoomSummary.Filled && roomSummary.details.isDirect
|
||||
}
|
||||
RoomListFilter.Favorite -> { roomSummary: RoomSummary ->
|
||||
roomSummary is RoomSummary.Filled && roomSummary.details.isFavorite
|
||||
}
|
||||
RoomListFilter.Unread -> { roomSummary: RoomSummary ->
|
||||
roomSummary is RoomSummary.Filled &&
|
||||
(roomSummary.details.numUnreadNotifications > 0 || roomSummary.details.isMarkedUnread)
|
||||
}
|
||||
is RoomListFilter.NormalizedMatchRoomName -> { roomSummary: RoomSummary ->
|
||||
roomSummary is RoomSummary.Filled && roomSummary.details.name.contains(pattern, ignoreCase = true)
|
||||
}
|
||||
}
|
||||
|
||||
fun List<RoomSummary>.filter(filter: RoomListFilter): List<RoomSummary> {
|
||||
return when (filter) {
|
||||
is RoomListFilter.All -> {
|
||||
val predicates = filter.filters.map { it.predicate }
|
||||
filter { roomSummary -> predicates.all { it(roomSummary) } }
|
||||
}
|
||||
is RoomListFilter.Any -> {
|
||||
val predicates = filter.filters.map { it.predicate }
|
||||
filter { roomSummary -> predicates.any { it(roomSummary) } }
|
||||
}
|
||||
else -> filter(filter.predicate)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ internal class RustRoomListService(
|
|||
private val roomListFactory: RoomListFactory,
|
||||
) : RoomListService {
|
||||
override fun createRoomList(
|
||||
coroutineScope: CoroutineScope,
|
||||
pageSize: Int,
|
||||
initialFilter: RoomListFilter,
|
||||
source: RoomList.Source
|
||||
|
|
@ -55,7 +54,6 @@ internal class RustRoomListService(
|
|||
return roomListFactory.createRoomList(
|
||||
pageSize = pageSize,
|
||||
initialFilter = initialFilter,
|
||||
coroutineScope = coroutineScope,
|
||||
coroutineContext = sessionDispatcher,
|
||||
) {
|
||||
when (source) {
|
||||
|
|
@ -68,7 +66,6 @@ internal class RustRoomListService(
|
|||
override val allRooms: DynamicRoomList = roomListFactory.createRoomList(
|
||||
pageSize = DEFAULT_PAGE_SIZE,
|
||||
coroutineContext = sessionDispatcher,
|
||||
initialFilter = RoomListFilter.all(RoomListFilter.NonLeft),
|
||||
) {
|
||||
innerRoomListService.allRooms()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue