Return cached room members before fetching new ones, do it in batches (#2274)
* Use cached users from the Rust SDK. Also lazy load received users by batches. * Create `RoomMemberListFetcher` to wrap all the room member loading logic * Ensure we clear `RoomMember` Rust references if the fetching coroutine is canceled
This commit is contained in:
parent
83267173c7
commit
f9c5cd07a9
17 changed files with 579 additions and 84 deletions
|
|
@ -26,11 +26,13 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomEvent
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomPresenter
|
||||
import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsPresenter
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||
import io.element.android.libraries.designsystem.utils.OnLifecycleEvent
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
|
|
@ -76,7 +78,13 @@ class RoomDetailsPresenter @Inject constructor(
|
|||
room.updateRoomNotificationSettings()
|
||||
observeNotificationSettings()
|
||||
}
|
||||
room.updateMembers()
|
||||
}
|
||||
|
||||
// Update room members only when first presenting the node
|
||||
OnLifecycleEvent { _, event ->
|
||||
if (event == Lifecycle.Event.ON_CREATE) {
|
||||
scope.launch { room.updateMembers() }
|
||||
}
|
||||
}
|
||||
|
||||
val membersState by room.membersStateFlow.collectAsState()
|
||||
|
|
|
|||
|
|
@ -19,11 +19,8 @@ package io.element.android.features.roomdetails.impl.members
|
|||
import io.element.android.libraries.core.bool.orFalse
|
||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
|
||||
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||
import io.element.android.libraries.matrix.api.room.roomMembers
|
||||
import kotlinx.coroutines.flow.dropWhile
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -32,11 +29,8 @@ class RoomMemberListDataSource @Inject constructor(
|
|||
private val coroutineDispatchers: CoroutineDispatchers,
|
||||
) {
|
||||
suspend fun search(query: String): List<RoomMember> = withContext(coroutineDispatchers.io) {
|
||||
val roomMembers = room.membersStateFlow
|
||||
.dropWhile { it !is MatrixRoomMembersState.Ready }
|
||||
.first()
|
||||
.roomMembers()
|
||||
.orEmpty()
|
||||
val roomMembersState = room.membersStateFlow.value
|
||||
val roomMembers = roomMembersState.roomMembers().orEmpty()
|
||||
val filteredMembers = if (query.isBlank()) {
|
||||
roomMembers
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -30,8 +30,10 @@ import io.element.android.libraries.architecture.Presenter
|
|||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
|
||||
import io.element.android.libraries.matrix.api.room.RoomMembershipState
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.canInvite
|
||||
import io.element.android.libraries.matrix.api.room.roomMembers
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
|
@ -55,9 +57,12 @@ class RoomMemberListPresenter @Inject constructor(
|
|||
value = room.canInvite().getOrElse { false }
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
LaunchedEffect(membersState) {
|
||||
if (membersState is MatrixRoomMembersState.Unknown) {
|
||||
return@LaunchedEffect
|
||||
}
|
||||
withContext(coroutineDispatchers.io) {
|
||||
val members = roomMemberListDataSource.search("").groupBy { it.membership }
|
||||
val members = membersState.roomMembers().orEmpty().groupBy { it.membership }
|
||||
roomMembers = AsyncData.Success(
|
||||
RoomMembers(
|
||||
invited = members.getOrDefault(RoomMembershipState.INVITE, emptyList()).toImmutableList(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue