RolesAndPermissionsEvents -> RolesAndPermissionsEvent

This commit is contained in:
Benoit Marty
2026-08-25 10:15:35 +02:00
parent fc8d3b3065
commit 4e2d99c968
7 changed files with 44 additions and 44 deletions
@@ -10,9 +10,9 @@ package io.element.android.features.rolesandpermissions.impl.root
import io.element.android.libraries.matrix.api.room.RoomMember
sealed interface RolesAndPermissionsEvents {
data object ChangeOwnRole : RolesAndPermissionsEvents
data class DemoteSelfTo(val role: RoomMember.Role) : RolesAndPermissionsEvents
data object ResetPermissions : RolesAndPermissionsEvents
data object CancelPendingAction : RolesAndPermissionsEvents
sealed interface RolesAndPermissionsEvent {
data object ChangeOwnRole : RolesAndPermissionsEvent
data class DemoteSelfTo(val role: RoomMember.Role) : RolesAndPermissionsEvent
data object ResetPermissions : RolesAndPermissionsEvent
data object CancelPendingAction : RolesAndPermissionsEvent
}
@@ -63,20 +63,20 @@ class RolesAndPermissionsPresenter(
val changeOwnRoleAction = remember { mutableStateOf<AsyncAction<Unit>>(AsyncAction.Uninitialized) }
val resetPermissionsAction = remember { mutableStateOf<AsyncAction<Unit>>(AsyncAction.Uninitialized) }
fun handleEvent(event: RolesAndPermissionsEvents) {
fun handleEvent(event: RolesAndPermissionsEvent) {
when (event) {
is RolesAndPermissionsEvents.ChangeOwnRole -> {
is RolesAndPermissionsEvent.ChangeOwnRole -> {
changeOwnRoleAction.value = AsyncAction.ConfirmingNoParams
}
is RolesAndPermissionsEvents.CancelPendingAction -> {
is RolesAndPermissionsEvent.CancelPendingAction -> {
changeOwnRoleAction.value = AsyncAction.Uninitialized
resetPermissionsAction.value = AsyncAction.Uninitialized
}
is RolesAndPermissionsEvents.DemoteSelfTo -> coroutineScope.demoteSelfTo(
is RolesAndPermissionsEvent.DemoteSelfTo -> coroutineScope.demoteSelfTo(
role = event.role,
changeOwnRoleAction = changeOwnRoleAction,
)
is RolesAndPermissionsEvents.ResetPermissions -> if (resetPermissionsAction.value.isConfirming()) {
is RolesAndPermissionsEvent.ResetPermissions -> if (resetPermissionsAction.value.isConfirming()) {
coroutineScope.resetPermissions(resetPermissionsAction)
} else {
resetPermissionsAction.value = AsyncAction.ConfirmingNoParams
@@ -20,7 +20,7 @@ data class RolesAndPermissionsState(
val availableSelfDemoteActions: ImmutableList<SelfDemoteAction>,
val changeOwnRoleAction: AsyncAction<Unit>,
val resetPermissionsAction: AsyncAction<Unit>,
val eventSink: (RolesAndPermissionsEvents) -> Unit,
val eventSink: (RolesAndPermissionsEvent) -> Unit,
) {
val canSelfDemote = availableSelfDemoteActions.isNotEmpty()
}
@@ -58,7 +58,7 @@ internal fun aRolesAndPermissionsState(
availableSelfDemoteActions: List<SelfDemoteAction> = listOf(SelfDemoteAction.ToModerator, SelfDemoteAction.ToMember),
changeOwnRoleAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
resetPermissionsAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
eventSink: (RolesAndPermissionsEvents) -> Unit = {},
eventSink: (RolesAndPermissionsEvent) -> Unit = {},
) = RolesAndPermissionsState(
roomSupportsOwnerRole = roomSupportsOwners,
adminCount = adminCount,
@@ -80,7 +80,7 @@ fun RolesAndPermissionsView(
if (state.canSelfDemote) {
ListItem(
content = { Text(stringResource(R.string.screen_room_roles_and_permissions_change_my_role)) },
onClick = { state.eventSink(RolesAndPermissionsEvents.ChangeOwnRole) },
onClick = { state.eventSink(RolesAndPermissionsEvent.ChangeOwnRole) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Edit()))
)
}
@@ -94,7 +94,7 @@ fun RolesAndPermissionsView(
ListItem(
content = { Text(stringResource(R.string.screen_room_roles_and_permissions_reset)) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Delete())),
onClick = { state.eventSink(RolesAndPermissionsEvents.ResetPermissions) },
onClick = { state.eventSink(RolesAndPermissionsEvent.ResetPermissions) },
style = ListItemStyle.Destructive,
)
}
@@ -107,12 +107,12 @@ fun RolesAndPermissionsView(
content = stringResource(R.string.screen_room_roles_and_permissions_reset_confirm_description),
submitText = stringResource(CommonStrings.action_reset),
destructiveSubmit = true,
onSubmitClick = { state.eventSink(RolesAndPermissionsEvents.ResetPermissions) },
onDismiss = { state.eventSink(RolesAndPermissionsEvents.CancelPendingAction) },
onSubmitClick = { state.eventSink(RolesAndPermissionsEvent.ResetPermissions) },
onDismiss = { state.eventSink(RolesAndPermissionsEvent.CancelPendingAction) },
)
},
onSuccess = { state.eventSink(RolesAndPermissionsEvents.CancelPendingAction) },
onErrorDismiss = { state.eventSink(RolesAndPermissionsEvents.CancelPendingAction) }
onSuccess = { state.eventSink(RolesAndPermissionsEvent.CancelPendingAction) },
onErrorDismiss = { state.eventSink(RolesAndPermissionsEvent.CancelPendingAction) }
)
when (state.changeOwnRoleAction) {
@@ -128,7 +128,7 @@ fun RolesAndPermissionsView(
is AsyncAction.Failure -> {
ErrorDialog(
content = stringResource(CommonStrings.error_unknown),
onSubmit = { state.eventSink(RolesAndPermissionsEvents.CancelPendingAction) }
onSubmit = { state.eventSink(RolesAndPermissionsEvent.CancelPendingAction) }
)
}
else -> Unit
@@ -139,7 +139,7 @@ fun RolesAndPermissionsView(
@Composable
private fun ChangeOwnRoleBottomSheet(
availableDemoteActions: ImmutableList<SelfDemoteAction>,
eventSink: (RolesAndPermissionsEvents) -> Unit,
eventSink: (RolesAndPermissionsEvent) -> Unit,
) {
val coroutineScope = rememberCoroutineScope()
val sheetState = rememberBottomSheetState(
@@ -148,7 +148,7 @@ private fun ChangeOwnRoleBottomSheet(
)
fun dismiss() {
sheetState.hide(coroutineScope) {
eventSink(RolesAndPermissionsEvents.CancelPendingAction)
eventSink(RolesAndPermissionsEvent.CancelPendingAction)
}
}
ModalBottomSheet(
@@ -176,7 +176,7 @@ private fun ChangeOwnRoleBottomSheet(
content = { Text(stringResource(demoteAction.titleRes)) },
onClick = {
sheetState.hide(coroutineScope) {
eventSink(RolesAndPermissionsEvents.DemoteSelfTo(demoteAction.role))
eventSink(RolesAndPermissionsEvent.DemoteSelfTo(demoteAction.role))
}
},
style = ListItemStyle.Destructive,
@@ -45,7 +45,7 @@ class RolesAndPermissionPresenterTest {
val presenter = createRolesAndPermissionsPresenter()
presenter.test {
val initialState = awaitItem()
initialState.eventSink(RolesAndPermissionsEvents.ChangeOwnRole)
initialState.eventSink(RolesAndPermissionsEvent.ChangeOwnRole)
assertThat(awaitItem().changeOwnRoleAction).isEqualTo(AsyncAction.ConfirmingNoParams)
}
}
@@ -62,7 +62,7 @@ class RolesAndPermissionPresenterTest {
)
presenter.test {
val initialState = awaitItem()
initialState.eventSink(RolesAndPermissionsEvents.DemoteSelfTo(RoomMember.Role.Moderator))
initialState.eventSink(RolesAndPermissionsEvent.DemoteSelfTo(RoomMember.Role.Moderator))
runCurrent()
assertThat(awaitItem().changeOwnRoleAction).isEqualTo(AsyncAction.Loading)
@@ -82,7 +82,7 @@ class RolesAndPermissionPresenterTest {
val presenter = createRolesAndPermissionsPresenter(room = room, dispatchers = testCoroutineDispatchers())
presenter.test {
val initialState = awaitItem()
initialState.eventSink(RolesAndPermissionsEvents.DemoteSelfTo(RoomMember.Role.Moderator))
initialState.eventSink(RolesAndPermissionsEvent.DemoteSelfTo(RoomMember.Role.Moderator))
runCurrent()
assertThat(awaitItem().changeOwnRoleAction).isEqualTo(AsyncAction.Loading)
@@ -90,7 +90,7 @@ class RolesAndPermissionPresenterTest {
runCurrent()
assertThat(awaitItem().changeOwnRoleAction).isInstanceOf(AsyncAction.Failure::class.java)
initialState.eventSink(RolesAndPermissionsEvents.CancelPendingAction)
initialState.eventSink(RolesAndPermissionsEvent.CancelPendingAction)
assertThat(awaitItem().changeOwnRoleAction).isEqualTo(AsyncAction.Uninitialized)
}
}
@@ -100,8 +100,8 @@ class RolesAndPermissionPresenterTest {
val presenter = createRolesAndPermissionsPresenter()
presenter.test {
val initialState = awaitItem()
initialState.eventSink(RolesAndPermissionsEvents.ChangeOwnRole)
awaitItem().eventSink(RolesAndPermissionsEvents.CancelPendingAction)
initialState.eventSink(RolesAndPermissionsEvent.ChangeOwnRole)
awaitItem().eventSink(RolesAndPermissionsEvent.CancelPendingAction)
assertThat(awaitItem().changeOwnRoleAction).isEqualTo(AsyncAction.Uninitialized)
}
@@ -119,9 +119,9 @@ class RolesAndPermissionPresenterTest {
)
presenter.test {
val initialState = awaitItem()
initialState.eventSink(RolesAndPermissionsEvents.ResetPermissions)
initialState.eventSink(RolesAndPermissionsEvent.ResetPermissions)
// Confirmation
awaitItem().eventSink(RolesAndPermissionsEvents.ResetPermissions)
awaitItem().eventSink(RolesAndPermissionsEvent.ResetPermissions)
assertThat(awaitItem().resetPermissionsAction).isEqualTo(AsyncAction.Loading)
assertThat(awaitItem().resetPermissionsAction).isEqualTo(AsyncAction.Success(Unit))
@@ -134,8 +134,8 @@ class RolesAndPermissionPresenterTest {
val presenter = createRolesAndPermissionsPresenter()
presenter.test {
val initialState = awaitItem()
initialState.eventSink(RolesAndPermissionsEvents.ResetPermissions)
awaitItem().eventSink(RolesAndPermissionsEvents.CancelPendingAction)
initialState.eventSink(RolesAndPermissionsEvent.ResetPermissions)
awaitItem().eventSink(RolesAndPermissionsEvent.CancelPendingAction)
assertThat(awaitItem().resetPermissionsAction).isEqualTo(AsyncAction.Uninitialized)
}
@@ -92,19 +92,19 @@ class RolesAndPermissionsViewTest : RobolectricTest() {
@Test
@Config(qualifiers = "h640dp")
fun `tapping on reset permissions triggers ResetPermissions event`() = runAndroidComposeUiTest {
val recorder = EventsRecorder<RolesAndPermissionsEvents>()
val recorder = EventsRecorder<RolesAndPermissionsEvent>()
setRolesAndPermissionsView(
state = aRolesAndPermissionsState(
eventSink = recorder,
),
)
clickOn(R.string.screen_room_roles_and_permissions_reset)
recorder.assertSingle(RolesAndPermissionsEvents.ResetPermissions)
recorder.assertSingle(RolesAndPermissionsEvent.ResetPermissions)
}
@Test
fun `tapping on Reset in the reset permissions confirmation dialog triggers ResetPermissions event`() = runAndroidComposeUiTest {
val recorder = EventsRecorder<RolesAndPermissionsEvents>()
val recorder = EventsRecorder<RolesAndPermissionsEvent>()
setRolesAndPermissionsView(
state = aRolesAndPermissionsState(
resetPermissionsAction = AsyncAction.ConfirmingNoParams,
@@ -112,12 +112,12 @@ class RolesAndPermissionsViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_reset)
recorder.assertSingle(RolesAndPermissionsEvents.ResetPermissions)
recorder.assertSingle(RolesAndPermissionsEvent.ResetPermissions)
}
@Test
fun `tapping on Cancel in the reset permissions confirmation dialog triggers CancelPendingAction event`() = runAndroidComposeUiTest {
val recorder = EventsRecorder<RolesAndPermissionsEvents>()
val recorder = EventsRecorder<RolesAndPermissionsEvent>()
setRolesAndPermissionsView(
state = aRolesAndPermissionsState(
resetPermissionsAction = AsyncAction.ConfirmingNoParams,
@@ -125,12 +125,12 @@ class RolesAndPermissionsViewTest : RobolectricTest() {
),
)
clickOn(CommonStrings.action_cancel)
recorder.assertSingle(RolesAndPermissionsEvents.CancelPendingAction)
recorder.assertSingle(RolesAndPermissionsEvent.CancelPendingAction)
}
@Test
fun `tapping on 'Demote to moderator' in the demote self bottom sheet triggers the right event`() = runAndroidComposeUiTest {
val recorder = EventsRecorder<RolesAndPermissionsEvents>()
val recorder = EventsRecorder<RolesAndPermissionsEvent>()
setRolesAndPermissionsView(
state = aRolesAndPermissionsState(
changeOwnRoleAction = AsyncAction.ConfirmingNoParams,
@@ -139,12 +139,12 @@ class RolesAndPermissionsViewTest : RobolectricTest() {
)
clickOn(R.string.screen_room_roles_and_permissions_change_role_demote_to_moderator)
mainClock.advanceTimeBy(1_000L)
recorder.assertSingle(RolesAndPermissionsEvents.DemoteSelfTo(RoomMember.Role.Moderator))
recorder.assertSingle(RolesAndPermissionsEvent.DemoteSelfTo(RoomMember.Role.Moderator))
}
@Test
fun `tapping on 'Demote to member' in the demote self bottom sheet triggers the right event`() = runAndroidComposeUiTest {
val recorder = EventsRecorder<RolesAndPermissionsEvents>()
val recorder = EventsRecorder<RolesAndPermissionsEvent>()
setRolesAndPermissionsView(
state = aRolesAndPermissionsState(
changeOwnRoleAction = AsyncAction.ConfirmingNoParams,
@@ -153,12 +153,12 @@ class RolesAndPermissionsViewTest : RobolectricTest() {
)
clickOn(R.string.screen_room_roles_and_permissions_change_role_demote_to_member)
mainClock.advanceTimeBy(1_000L)
recorder.assertSingle(RolesAndPermissionsEvents.DemoteSelfTo(RoomMember.Role.User))
recorder.assertSingle(RolesAndPermissionsEvent.DemoteSelfTo(RoomMember.Role.User))
}
@Test
fun `tapping on 'Cancel' in the demote self bottom sheet triggers the right event`() = runAndroidComposeUiTest {
val recorder = EventsRecorder<RolesAndPermissionsEvents>()
val recorder = EventsRecorder<RolesAndPermissionsEvent>()
setRolesAndPermissionsView(
state = aRolesAndPermissionsState(
changeOwnRoleAction = AsyncAction.ConfirmingNoParams,
@@ -167,7 +167,7 @@ class RolesAndPermissionsViewTest : RobolectricTest() {
)
clickOn(CommonStrings.action_cancel)
mainClock.advanceTimeBy(1_000L)
recorder.assertSingle(RolesAndPermissionsEvents.CancelPendingAction)
recorder.assertSingle(RolesAndPermissionsEvent.CancelPendingAction)
}
}