RoomListFilters : use kotlin filtering as rust one is slower and has more chance to bust the room list cache.

This commit is contained in:
ganfra 2024-02-27 16:24:54 +01:00
parent 593a94b994
commit bd87e99df1
13 changed files with 278 additions and 112 deletions

View file

@ -83,7 +83,7 @@ class RoomListFiltersPresenter @Inject constructor(
RoomListFilter.Unread -> MatrixRoomListFilter.Unread
RoomListFilter.Favourites -> MatrixRoomListFilter.Favorite
}
}.plus(MatrixRoomListFilter.NonLeft)
}
)
roomListService.allRooms.updateFilter(allRoomsFilter)
}

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2024 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.features.roomlist.impl.search
import io.element.android.features.roomlist.impl.datasource.RoomListRoomSummaryFactory
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.matrix.api.roomlist.RoomList
import io.element.android.libraries.matrix.api.roomlist.RoomListFilter
import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.api.roomlist.loadAllIncrementally
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import javax.inject.Inject
private const val PAGE_SIZE = 30
class RoomListSearchDataSource @Inject constructor(
roomListService: RoomListService,
coroutineDispatchers: CoroutineDispatchers,
private val roomSummaryFactory: RoomListRoomSummaryFactory,
) {
private val roomList = roomListService.createRoomList(
pageSize = PAGE_SIZE,
initialFilter = RoomListFilter.None,
source = RoomList.Source.All,
)
val roomSummaries: Flow<PersistentList<RoomListRoomSummary>> = roomList.summaries
.map { roomSummaries ->
roomSummaries
.filterIsInstance<RoomSummary.Filled>()
.map(roomSummaryFactory::create)
.toPersistentList()
}
.flowOn(coroutineDispatchers.computation)
suspend fun setIsActive(isActive: Boolean) = coroutineScope {
if (isActive) {
roomList.loadAllIncrementally(this)
} else {
roomList.reset()
}
}
suspend fun setSearchQuery(searchQuery: String) = coroutineScope {
val filter = if (searchQuery.isBlank()) {
RoomListFilter.None
} else {
RoomListFilter.NormalizedMatchRoomName(searchQuery)
}
roomList.updateFilter(filter)
}
}

View file

@ -21,30 +21,14 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import io.element.android.features.roomlist.impl.datasource.RoomListRoomSummaryFactory
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.matrix.api.roomlist.RoomList
import io.element.android.libraries.matrix.api.roomlist.RoomListFilter
import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.api.roomlist.loadAllIncrementally
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import javax.inject.Inject
private const val PAGE_SIZE = 50
class RoomListSearchPresenter @Inject constructor(
private val roomListService: RoomListService,
private val roomSummaryFactory: RoomListRoomSummaryFactory,
private val coroutineDispatchers: CoroutineDispatchers,
private val dataSource: RoomListSearchDataSource,
) : Presenter<RoomListSearchState> {
@Composable
override fun present(): RoomListSearchState {
@ -54,27 +38,13 @@ class RoomListSearchPresenter @Inject constructor(
var searchQuery by rememberSaveable {
mutableStateOf("")
}
val coroutineScope = rememberCoroutineScope()
val roomList = remember {
roomListService.createRoomList(
coroutineScope = coroutineScope,
pageSize = PAGE_SIZE,
initialFilter = RoomListFilter.all(RoomListFilter.None),
source = RoomList.Source.All,
)
LaunchedEffect(isSearchActive) {
dataSource.setIsActive(isSearchActive)
}
LaunchedEffect(Unit) {
roomList.loadAllIncrementally(this)
}
LaunchedEffect(key1 = searchQuery) {
val filter = if (searchQuery.isBlank()) {
RoomListFilter.all(RoomListFilter.None)
} else {
RoomListFilter.all(RoomListFilter.NonLeft, RoomListFilter.NormalizedMatchRoomName(searchQuery))
}
roomList.updateFilter(filter)
LaunchedEffect(searchQuery) {
dataSource.setSearchQuery(searchQuery)
}
fun handleEvents(event: RoomListSearchEvents) {
@ -92,9 +62,7 @@ class RoomListSearchPresenter @Inject constructor(
}
}
val searchResults by roomList
.rememberMappedSummaries()
.collectAsState(initial = persistentListOf())
val searchResults by dataSource.roomSummaries.collectAsState(initial = persistentListOf())
return RoomListSearchState(
isSearchActive = isSearchActive,
@ -103,16 +71,4 @@ class RoomListSearchPresenter @Inject constructor(
eventSink = ::handleEvents
)
}
@Composable
private fun RoomList.rememberMappedSummaries() = remember {
summaries
.map { roomSummaries ->
roomSummaries
.filterIsInstance<RoomSummary.Filled>()
.map(roomSummaryFactory::create)
.toPersistentList()
}
.flowOn(coroutineDispatchers.computation)
}
}