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:
parent
25da1cba83
commit
2eacce47c0
6 changed files with 61 additions and 23 deletions
|
|
@ -38,10 +38,12 @@ import kotlinx.collections.immutable.PersistentList
|
|||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.drop
|
||||
import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
class RoomMemberModerationPresenter @Inject constructor(
|
||||
private val room: JoinedRoom,
|
||||
|
|
@ -82,6 +84,9 @@ class RoomMemberModerationPresenter @Inject constructor(
|
|||
)
|
||||
}
|
||||
is RoomMemberModerationEvents.ProcessAction -> {
|
||||
// First, hide any list of existing actions that could be displayed
|
||||
moderationActions.value = persistentListOf()
|
||||
|
||||
when (event.action) {
|
||||
is ModerationAction.DisplayProfile -> Unit
|
||||
is ModerationAction.KickUser -> {
|
||||
|
|
@ -118,6 +123,7 @@ class RoomMemberModerationPresenter @Inject constructor(
|
|||
}
|
||||
is InternalRoomMemberModerationEvents.Reset -> {
|
||||
selectedUser = null
|
||||
moderationActions.value = persistentListOf()
|
||||
kickUserAsyncAction.value = AsyncAction.Uninitialized
|
||||
banUserAsyncAction.value = AsyncAction.Uninitialized
|
||||
unbanUserAsyncAction.value = AsyncAction.Uninitialized
|
||||
|
|
@ -204,7 +210,15 @@ class RoomMemberModerationPresenter @Inject constructor(
|
|||
action.runUpdatingState {
|
||||
val result = block()
|
||||
if (result.isSuccess) {
|
||||
room.membersStateFlow.drop(1).take(1)
|
||||
// We wait a bit to ensure the server has processed the membership change
|
||||
delay(50.milliseconds)
|
||||
|
||||
// Update the members to ensure we have the latest state
|
||||
launch { room.updateMembers() }
|
||||
|
||||
// Wait for the membership change to be processed and returned
|
||||
// We drop the first emission as it's the current state
|
||||
room.membersStateFlow.drop(1).first()
|
||||
}
|
||||
result
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import io.element.android.services.analytics.test.FakeAnalyticsService
|
|||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.test
|
||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runTest
|
||||
|
|
@ -217,7 +218,14 @@ class RoomMemberModerationPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - do kick user with success`() = runTest {
|
||||
createRoomMemberModerationPresenter(room = aJoinedRoom()).test {
|
||||
val room = aJoinedRoom()
|
||||
room.baseRoom.givenUpdateMembersResult {
|
||||
// Simulate the member list being updated
|
||||
room.givenRoomMembersState(RoomMembersState.Ready(
|
||||
persistentListOf(aRoomMember())
|
||||
))
|
||||
}
|
||||
createRoomMemberModerationPresenter(room = room).test {
|
||||
val initialState = awaitState()
|
||||
initialState.eventSink(
|
||||
RoomMemberModerationEvents.ProcessAction(
|
||||
|
|
@ -238,7 +246,14 @@ class RoomMemberModerationPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - do ban user with success`() = runTest {
|
||||
createRoomMemberModerationPresenter(room = aJoinedRoom()).test {
|
||||
val room = aJoinedRoom()
|
||||
room.baseRoom.givenUpdateMembersResult {
|
||||
// Simulate the member list being updated
|
||||
room.givenRoomMembersState(RoomMembersState.Ready(
|
||||
persistentListOf(aRoomMember())
|
||||
))
|
||||
}
|
||||
createRoomMemberModerationPresenter(room = room).test {
|
||||
val initialState = awaitState()
|
||||
initialState.eventSink(
|
||||
RoomMemberModerationEvents.ProcessAction(
|
||||
|
|
@ -259,7 +274,14 @@ class RoomMemberModerationPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `present - do unban user with success`() = runTest {
|
||||
createRoomMemberModerationPresenter(room = aJoinedRoom()).test {
|
||||
val room = aJoinedRoom()
|
||||
room.baseRoom.givenUpdateMembersResult {
|
||||
// Simulate the member list being updated
|
||||
room.givenRoomMembersState(RoomMembersState.Ready(
|
||||
persistentListOf(aRoomMember())
|
||||
))
|
||||
}
|
||||
createRoomMemberModerationPresenter(room = room).test {
|
||||
val initialState = awaitState()
|
||||
initialState.eventSink(
|
||||
RoomMemberModerationEvents.ProcessAction(
|
||||
|
|
@ -326,7 +348,7 @@ class RoomMemberModerationPresenterTest {
|
|||
banUserResult: Result<Unit> = Result.success(Unit),
|
||||
unBanUserResult: Result<Unit> = Result.success(Unit),
|
||||
targetRoomMember: RoomMember? = null,
|
||||
): JoinedRoom {
|
||||
): FakeJoinedRoom {
|
||||
return FakeJoinedRoom(
|
||||
kickUserResult = { _, _ -> kickUserResult },
|
||||
banUserResult = { _, _ -> banUserResult },
|
||||
|
|
@ -335,6 +357,7 @@ class RoomMemberModerationPresenterTest {
|
|||
canBanResult = { _ -> Result.success(canBan) },
|
||||
canKickResult = { _ -> Result.success(canKick) },
|
||||
userRoleResult = { Result.success(myUserRole) },
|
||||
updateMembersResult = { Result.success(Unit) }
|
||||
),
|
||||
).apply {
|
||||
val roomMembers = listOfNotNull(targetRoomMember).toPersistentList()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue