Reload member list after moderation actions (#5268)

* Reload member list after moderation actions

The previous `runActionAndWaitForMembershipChange` logic wasn't really doing anything, as the modified flow was never used.

* Make sure we always set the value in the member list state flow, even if the underlying coroutine scope is no longer there.

With `emit`, the `Ready` state was not emitted if the member list was loaded way too fast.
This commit is contained in:
Jorge Martin Espinosa 2025-09-04 14:56:46 +02:00 committed by GitHub
parent 25da1cba83
commit 2eacce47c0
6 changed files with 61 additions and 23 deletions

View file

@ -79,35 +79,35 @@ internal class RoomMemberListFetcher(
Timber.i("Loading cached members for room $roomId")
try {
// Send current member list with pending state to notify the UI that we are loading new members
emit(pendingWithCurrentMembers())
value = pendingWithCurrentMembers()
val members = parseAndEmitMembers(room.membersNoSync())
val newState = if (asPendingState) {
RoomMembersState.Pending(prevRoomMembers = members)
} else {
RoomMembersState.Ready(members)
}
emit(newState)
value = newState
} catch (exception: CancellationException) {
Timber.d("Cancelled loading cached members for room $roomId")
throw exception
} catch (exception: Exception) {
Timber.e(exception, "Failed to load cached members for room $roomId")
emit(RoomMembersState.Error(exception, _membersFlow.value.roomMembers()?.toImmutableList()))
value = RoomMembersState.Error(exception, _membersFlow.value.roomMembers()?.toImmutableList())
}
}
private suspend fun MutableStateFlow<RoomMembersState>.fetchRemoteRoomMembers() {
try {
// Send current member list with pending state to notify the UI that we are loading new members
emit(pendingWithCurrentMembers())
value = pendingWithCurrentMembers()
// Start loading new members
emit(RoomMembersState.Ready(parseAndEmitMembers(room.members())))
value = RoomMembersState.Ready(parseAndEmitMembers(room.members()))
} catch (exception: CancellationException) {
Timber.d("Cancelled loading updated members for room $roomId")
throw exception
} catch (exception: Exception) {
Timber.e(exception, "Failed to load updated members for room $roomId")
emit(RoomMembersState.Error(exception, _membersFlow.value.roomMembers()?.toImmutableList()))
value = RoomMembersState.Error(exception, _membersFlow.value.roomMembers()?.toImmutableList())
}
}

View file

@ -59,7 +59,7 @@ class FakeBaseRoom(
private val markAsReadResult: (ReceiptType) -> Result<Unit> = { Result.success(Unit) },
private val powerLevelsResult: () -> Result<RoomPowerLevelsValues> = { lambdaError() },
private val leaveRoomLambda: () -> Result<Unit> = { lambdaError() },
private val updateMembersResult: () -> Unit = { lambdaError() },
private var updateMembersResult: () -> Unit = { lambdaError() },
private val getMembersResult: (Int) -> Result<List<RoomMember>> = { lambdaError() },
private val saveComposerDraftLambda: (ComposerDraft) -> Result<Unit> = { _: ComposerDraft -> Result.success(Unit) },
private val loadComposerDraftLambda: () -> Result<ComposerDraft?> = { Result.success<ComposerDraft?>(null) },
@ -223,6 +223,10 @@ class FakeBaseRoom(
override suspend fun reportRoom(reason: String?) = reportRoomResult(reason)
override fun predecessorRoom(): PredecessorRoom? = predecessorRoomResult()
fun givenUpdateMembersResult(result: () -> Unit) {
updateMembersResult = result
}
}
fun defaultRoomPowerLevelValues() = RoomPowerLevelsValues(