LeaveSpaceEvents -> LeaveSpaceEvent

This commit is contained in:
Benoit Marty
2026-08-25 10:25:19 +02:00
parent a2c3ddab02
commit 15cdd85357
5 changed files with 30 additions and 30 deletions
@@ -10,11 +10,11 @@ package io.element.android.features.space.impl.leave
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
sealed interface LeaveSpaceEvents { sealed interface LeaveSpaceEvent {
data object Retry : LeaveSpaceEvents data object Retry : LeaveSpaceEvent
data object SelectAllRooms : LeaveSpaceEvents data object SelectAllRooms : LeaveSpaceEvent
data object DeselectAllRooms : LeaveSpaceEvents data object DeselectAllRooms : LeaveSpaceEvent
data class ToggleRoomSelection(val roomId: RoomId) : LeaveSpaceEvents data class ToggleRoomSelection(val roomId: RoomId) : LeaveSpaceEvent
data object LeaveSpace : LeaveSpaceEvents data object LeaveSpace : LeaveSpaceEvent
data object CloseError : LeaveSpaceEvents data object CloseError : LeaveSpaceEvent
} }
@@ -99,33 +99,33 @@ class LeaveSpacePresenter(
} }
} }
fun handleEvent(event: LeaveSpaceEvents) { fun handleEvent(event: LeaveSpaceEvent) {
when (event) { when (event) {
LeaveSpaceEvents.Retry -> { LeaveSpaceEvent.Retry -> {
leaveSpaceRooms = AsyncData.Loading() leaveSpaceRooms = AsyncData.Loading()
retryCount += 1 retryCount += 1
} }
LeaveSpaceEvents.DeselectAllRooms -> { LeaveSpaceEvent.DeselectAllRooms -> {
selectedRoomIds = persistentSetOf() selectedRoomIds = persistentSetOf()
} }
LeaveSpaceEvents.SelectAllRooms -> { LeaveSpaceEvent.SelectAllRooms -> {
selectedRoomIds = selectableSpaceRooms.dataOrNull() selectedRoomIds = selectableSpaceRooms.dataOrNull()
.orEmpty() .orEmpty()
.filter { it.isLastOwner.not() } .filter { it.isLastOwner.not() }
.map { it.spaceRoom.roomId } .map { it.spaceRoom.roomId }
} }
is LeaveSpaceEvents.ToggleRoomSelection -> { is LeaveSpaceEvent.ToggleRoomSelection -> {
selectedRoomIds = if (selectedRoomIds.contains(event.roomId)) { selectedRoomIds = if (selectedRoomIds.contains(event.roomId)) {
selectedRoomIds - event.roomId selectedRoomIds - event.roomId
} else { } else {
selectedRoomIds + event.roomId selectedRoomIds + event.roomId
} }
} }
LeaveSpaceEvents.LeaveSpace -> coroutineScope.leaveSpace( LeaveSpaceEvent.LeaveSpace -> coroutineScope.leaveSpace(
leaveSpaceAction = leaveSpaceAction, leaveSpaceAction = leaveSpaceAction,
selectedRoomIds = selectedRoomIds, selectedRoomIds = selectedRoomIds,
) )
LeaveSpaceEvents.CloseError -> { LeaveSpaceEvent.CloseError -> {
leaveSpaceAction.value = AsyncAction.Uninitialized leaveSpaceAction.value = AsyncAction.Uninitialized
} }
} }
@@ -19,7 +19,7 @@ data class LeaveSpaceState(
val areCreatorsPrivileged: Boolean, val areCreatorsPrivileged: Boolean,
val selectableSpaceRooms: AsyncData<ImmutableList<SelectableSpaceRoom>>, val selectableSpaceRooms: AsyncData<ImmutableList<SelectableSpaceRoom>>,
val leaveSpaceAction: AsyncAction<Unit>, val leaveSpaceAction: AsyncAction<Unit>,
val eventSink: (LeaveSpaceEvents) -> Unit, val eventSink: (LeaveSpaceEvent) -> Unit,
) { ) {
private val rooms = selectableSpaceRooms.dataOrNull().orEmpty().toImmutableList() private val rooms = selectableSpaceRooms.dataOrNull().orEmpty().toImmutableList()
private val lastAdminRooms: ImmutableList<SelectableSpaceRoom> private val lastAdminRooms: ImmutableList<SelectableSpaceRoom>
@@ -92,7 +92,7 @@ fun LeaveSpaceView(
showLeaveButton = state.showLeaveButton, showLeaveButton = state.showLeaveButton,
selectedRoomsCount = state.selectedRoomsCount, selectedRoomsCount = state.selectedRoomsCount,
onLeaveSpace = { onLeaveSpace = {
state.eventSink(LeaveSpaceEvents.LeaveSpace) state.eventSink(LeaveSpaceEvent.LeaveSpace)
}, },
onCancel = onCancel, onCancel = onCancel,
showRolesAndPermissionsButton = state.needsOwnerChange && !state.areCreatorsPrivileged, showRolesAndPermissionsButton = state.needsOwnerChange && !state.areCreatorsPrivileged,
@@ -115,7 +115,7 @@ fun LeaveSpaceView(
selectableSpaceRoom = selectableSpaceRoom, selectableSpaceRoom = selectableSpaceRoom,
showCheckBox = state.hasOnlyLastAdminRoom.not(), showCheckBox = state.hasOnlyLastAdminRoom.not(),
onClick = { onClick = {
state.eventSink(LeaveSpaceEvents.ToggleRoomSelection(selectableSpaceRoom.spaceRoom.roomId)) state.eventSink(LeaveSpaceEvent.ToggleRoomSelection(selectableSpaceRoom.spaceRoom.roomId))
} }
) )
} }
@@ -125,7 +125,7 @@ fun LeaveSpaceView(
AsyncFailure( AsyncFailure(
throwable = state.selectableSpaceRooms.error, throwable = state.selectableSpaceRooms.error,
onRetry = { onRetry = {
state.eventSink(LeaveSpaceEvents.Retry) state.eventSink(LeaveSpaceEvent.Retry)
}, },
) )
} }
@@ -143,7 +143,7 @@ fun LeaveSpaceView(
async = state.leaveSpaceAction, async = state.leaveSpaceAction,
onSuccess = { /* Nothing to do, the screen will be dismissed automatically */ }, onSuccess = { /* Nothing to do, the screen will be dismissed automatically */ },
errorMessage = { stringResource(CommonStrings.error_unknown) }, errorMessage = { stringResource(CommonStrings.error_unknown) },
onErrorDismiss = { state.eventSink(LeaveSpaceEvents.CloseError) }, onErrorDismiss = { state.eventSink(LeaveSpaceEvent.CloseError) },
) )
} }
@@ -184,11 +184,11 @@ private fun LeaveSpaceHeader(
if (state.showQuickAction) { if (state.showQuickAction) {
if (state.areAllSelected) { if (state.areAllSelected) {
QuickActionButton(CommonStrings.action_deselect_all) { QuickActionButton(CommonStrings.action_deselect_all) {
state.eventSink(LeaveSpaceEvents.DeselectAllRooms) state.eventSink(LeaveSpaceEvent.DeselectAllRooms)
} }
} else { } else {
QuickActionButton(resId = CommonStrings.action_select_all) { QuickActionButton(resId = CommonStrings.action_select_all) {
state.eventSink(LeaveSpaceEvents.SelectAllRooms) state.eventSink(LeaveSpaceEvent.SelectAllRooms)
} }
} }
} }
@@ -61,7 +61,7 @@ class LeaveSpacePresenterTest {
val stateError = awaitItem() val stateError = awaitItem()
assertThat(stateError.selectableSpaceRooms.isFailure()).isTrue() assertThat(stateError.selectableSpaceRooms.isFailure()).isTrue()
// Retry // Retry
stateError.eventSink(LeaveSpaceEvents.Retry) stateError.eventSink(LeaveSpaceEvent.Retry)
skipItems(1) skipItems(1)
val stateLoadingAgain = awaitItem() val stateLoadingAgain = awaitItem()
assertThat(stateLoadingAgain.selectableSpaceRooms.isLoading()).isTrue() assertThat(stateLoadingAgain.selectableSpaceRooms.isLoading()).isTrue()
@@ -121,7 +121,7 @@ class LeaveSpacePresenterTest {
assertThat(finalState.selectableSpaceRooms.dataOrNull()!!.map { it.spaceRoom.roomId }).containsExactly(A_ROOM_ID, A_ROOM_ID_3) assertThat(finalState.selectableSpaceRooms.dataOrNull()!!.map { it.spaceRoom.roomId }).containsExactly(A_ROOM_ID, A_ROOM_ID_3)
assertThat(finalState.selectedRoomsCount).isEqualTo(2) assertThat(finalState.selectedRoomsCount).isEqualTo(2)
// Leaving the space will not include the DM // Leaving the space will not include the DM
finalState.eventSink(LeaveSpaceEvents.LeaveSpace) finalState.eventSink(LeaveSpaceEvent.LeaveSpace)
val stateLeaving = awaitItem() val stateLeaving = awaitItem()
assertThat(stateLeaving.leaveSpaceAction).isEqualTo(AsyncAction.Loading) assertThat(stateLeaving.leaveSpaceAction).isEqualTo(AsyncAction.Loading)
val stateLeft = awaitItem() val stateLeft = awaitItem()
@@ -165,32 +165,32 @@ class LeaveSpacePresenterTest {
assertThat(room2.isSelected).isFalse() assertThat(room2.isSelected).isFalse()
assertThat(room2.isLastOwner).isTrue() assertThat(room2.isLastOwner).isTrue()
// Deselect all // Deselect all
state.eventSink(LeaveSpaceEvents.DeselectAllRooms) state.eventSink(LeaveSpaceEvent.DeselectAllRooms)
skipItems(1) skipItems(1)
val stateAllDeselected = awaitItem() val stateAllDeselected = awaitItem()
val dataAllDeselected = stateAllDeselected.selectableSpaceRooms.dataOrNull()!! val dataAllDeselected = stateAllDeselected.selectableSpaceRooms.dataOrNull()!!
assertThat(dataAllDeselected.any { it.isSelected }).isFalse() assertThat(dataAllDeselected.any { it.isSelected }).isFalse()
// Select all // Select all
stateAllDeselected.eventSink(LeaveSpaceEvents.SelectAllRooms) stateAllDeselected.eventSink(LeaveSpaceEvent.SelectAllRooms)
skipItems(1) skipItems(1)
val stateAllSelected = awaitItem() val stateAllSelected = awaitItem()
val dataAllSelected = stateAllSelected.selectableSpaceRooms.dataOrNull()!! val dataAllSelected = stateAllSelected.selectableSpaceRooms.dataOrNull()!!
// The last admin room should not be selected // The last admin room should not be selected
assertThat(dataAllSelected.count { it.isSelected }).isEqualTo(1) assertThat(dataAllSelected.count { it.isSelected }).isEqualTo(1)
// Toggle selection of the first room // Toggle selection of the first room
stateAllSelected.eventSink(LeaveSpaceEvents.ToggleRoomSelection(A_ROOM_ID)) stateAllSelected.eventSink(LeaveSpaceEvent.ToggleRoomSelection(A_ROOM_ID))
skipItems(1) skipItems(1)
val stateOneDeselected = awaitItem() val stateOneDeselected = awaitItem()
val dataOneDeselected = stateOneDeselected.selectableSpaceRooms.dataOrNull()!! val dataOneDeselected = stateOneDeselected.selectableSpaceRooms.dataOrNull()!!
assertThat(dataOneDeselected[0].isSelected).isFalse() assertThat(dataOneDeselected[0].isSelected).isFalse()
// Toggle selection of the first room // Toggle selection of the first room
stateOneDeselected.eventSink(LeaveSpaceEvents.ToggleRoomSelection(A_ROOM_ID)) stateOneDeselected.eventSink(LeaveSpaceEvent.ToggleRoomSelection(A_ROOM_ID))
skipItems(1) skipItems(1)
val stateOneSelected = awaitItem() val stateOneSelected = awaitItem()
val dataOneSelected = stateOneSelected.selectableSpaceRooms.dataOrNull()!! val dataOneSelected = stateOneSelected.selectableSpaceRooms.dataOrNull()!!
assertThat(dataOneSelected[0].isSelected).isTrue() assertThat(dataOneSelected[0].isSelected).isTrue()
// Leave space // Leave space
stateOneSelected.eventSink(LeaveSpaceEvents.LeaveSpace) stateOneSelected.eventSink(LeaveSpaceEvent.LeaveSpace)
val stateLeaving = awaitItem() val stateLeaving = awaitItem()
assertThat(stateLeaving.leaveSpaceAction).isEqualTo(AsyncAction.Loading) assertThat(stateLeaving.leaveSpaceAction).isEqualTo(AsyncAction.Loading)
val stateLeft = awaitItem() val stateLeft = awaitItem()
@@ -215,13 +215,13 @@ class LeaveSpacePresenterTest {
presenter.test { presenter.test {
skipItems(3) skipItems(3)
val state = awaitItem() val state = awaitItem()
state.eventSink(LeaveSpaceEvents.LeaveSpace) state.eventSink(LeaveSpaceEvent.LeaveSpace)
val stateLeaving = awaitItem() val stateLeaving = awaitItem()
assertThat(stateLeaving.leaveSpaceAction).isEqualTo(AsyncAction.Loading) assertThat(stateLeaving.leaveSpaceAction).isEqualTo(AsyncAction.Loading)
val stateError = awaitItem() val stateError = awaitItem()
assertThat(stateError.leaveSpaceAction.isFailure()).isTrue() assertThat(stateError.leaveSpaceAction.isFailure()).isTrue()
// Close error // Close error
stateError.eventSink(LeaveSpaceEvents.CloseError) stateError.eventSink(LeaveSpaceEvent.CloseError)
val stateErrorClosed = awaitItem() val stateErrorClosed = awaitItem()
assertThat(stateErrorClosed.leaveSpaceAction).isEqualTo(AsyncAction.Uninitialized) assertThat(stateErrorClosed.leaveSpaceAction).isEqualTo(AsyncAction.Uninitialized)
} }