Merge pull request #5845 from element-hq/feature/bma/unsavedChangeDialog

Update unsaved change dialog
This commit is contained in:
Benoit Marty 2025-12-04 11:03:42 +01:00 committed by GitHub
commit fbaedd017e
59 changed files with 537 additions and 468 deletions

View file

@ -73,8 +73,7 @@ class ChangeRoomPermissionsPresenter(
private var initialPermissions by mutableStateOf<RoomPowerLevelsValues?>(null)
private var currentPermissions by mutableStateOf<RoomPowerLevelsValues?>(null)
private var saveAction by mutableStateOf<AsyncAction<Unit>>(AsyncAction.Uninitialized)
private var confirmExitAction by mutableStateOf<AsyncAction<Unit>>(AsyncAction.Uninitialized)
private var saveAction by mutableStateOf<AsyncAction<Boolean>>(AsyncAction.Uninitialized)
@Composable
override fun present(): ChangeRoomPermissionsState {
@ -109,15 +108,14 @@ class ChangeRoomPermissionsPresenter(
}
is ChangeRoomPermissionsEvent.Save -> coroutineScope.save()
is ChangeRoomPermissionsEvent.Exit -> {
confirmExitAction = if (!hasChanges || confirmExitAction.isConfirming()) {
AsyncAction.Success(Unit)
saveAction = if (!hasChanges || saveAction == AsyncAction.ConfirmingCancellation) {
AsyncAction.Success(false)
} else {
AsyncAction.ConfirmingNoParams
AsyncAction.ConfirmingCancellation
}
}
is ChangeRoomPermissionsEvent.ResetPendingActions -> {
saveAction = AsyncAction.Uninitialized
confirmExitAction = AsyncAction.Uninitialized
}
}
}
@ -126,7 +124,6 @@ class ChangeRoomPermissionsPresenter(
itemsBySection = itemsBySection,
hasChanges = hasChanges,
saveAction = saveAction,
confirmExitAction = confirmExitAction,
eventSink = ::handleEvent,
)
}
@ -147,7 +144,7 @@ class ChangeRoomPermissionsPresenter(
.onSuccess {
analyticsService.trackPermissionChangeAnalytics(initialPermissions, updatedRoomPowerLevels)
initialPermissions = currentPermissions
saveAction = AsyncAction.Success(Unit)
saveAction = AsyncAction.Success(true)
}
.onFailure {
saveAction = AsyncAction.Failure(it)

View file

@ -23,8 +23,7 @@ data class ChangeRoomPermissionsState(
val currentPermissions: RoomPowerLevelsValues?,
val itemsBySection: ImmutableMap<RoomPermissionsSection, ImmutableList<RoomPermissionType>>,
val hasChanges: Boolean,
val saveAction: AsyncAction<Unit>,
val confirmExitAction: AsyncAction<Unit>,
val saveAction: AsyncAction<Boolean>,
val eventSink: (ChangeRoomPermissionsEvent) -> Unit,
) {
fun selectedRoleForType(type: RoomPermissionType): SelectableRole? {

View file

@ -25,7 +25,7 @@ class ChangeRoomPermissionsStateProvider : PreviewParameterProvider<ChangeRoomPe
hasChanges = true,
saveAction = AsyncAction.Failure(IllegalStateException("Failed to save changes"))
),
aChangeRoomPermissionsState(hasChanges = true, confirmExitAction = AsyncAction.ConfirmingNoParams),
aChangeRoomPermissionsState(hasChanges = true, saveAction = AsyncAction.ConfirmingCancellation),
)
}
@ -33,15 +33,13 @@ internal fun aChangeRoomPermissionsState(
currentPermissions: RoomPowerLevelsValues = previewPermissions(),
itemsBySection: Map<RoomPermissionsSection, ImmutableList<RoomPermissionType>> = ChangeRoomPermissionsPresenter.buildItems(false),
hasChanges: Boolean = false,
saveAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
confirmExitAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
saveAction: AsyncAction<Boolean> = AsyncAction.Uninitialized,
eventSink: (ChangeRoomPermissionsEvent) -> Unit = {},
) = ChangeRoomPermissionsState(
currentPermissions = currentPermissions,
itemsBySection = itemsBySection.toImmutableMap(),
hasChanges = hasChanges,
saveAction = saveAction,
confirmExitAction = confirmExitAction,
eventSink = eventSink,
)

View file

@ -18,9 +18,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter
import io.element.android.features.rolesandpermissions.impl.R
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.designsystem.components.async.AsyncActionView
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.libraries.designsystem.components.dialogs.SaveChangesDialog
import io.element.android.libraries.designsystem.components.preferences.PreferenceDropdown
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@ -91,24 +92,19 @@ fun ChangeRoomPermissionsView(
AsyncActionView(
async = state.saveAction,
onSuccess = { onComplete(true) },
onErrorDismiss = { state.eventSink(ChangeRoomPermissionsEvent.ResetPendingActions) }
)
AsyncActionView(
async = state.confirmExitAction,
onSuccess = { onComplete(false) },
confirmationDialog = {
ConfirmationDialog(
title = stringResource(R.string.screen_room_change_role_unsaved_changes_title),
content = stringResource(R.string.screen_room_change_role_unsaved_changes_description),
submitText = stringResource(CommonStrings.action_save),
cancelText = stringResource(CommonStrings.action_discard),
onSubmitClick = { state.eventSink(ChangeRoomPermissionsEvent.Save) },
onDismiss = { state.eventSink(ChangeRoomPermissionsEvent.Exit) }
)
onSuccess = { onComplete(it) },
confirmationDialog = { confirming ->
when (confirming) {
is AsyncAction.ConfirmingCancellation -> {
SaveChangesDialog(
onSaveClick = { state.eventSink(ChangeRoomPermissionsEvent.Save) },
onDiscardClick = { state.eventSink(ChangeRoomPermissionsEvent.Exit) },
onDismiss = { state.eventSink(ChangeRoomPermissionsEvent.ResetPendingActions) },
)
}
}
},
onErrorDismiss = {},
onErrorDismiss = { state.eventSink(ChangeRoomPermissionsEvent.ResetPendingActions) }
)
}

View file

@ -172,8 +172,9 @@ fun ChangeRolesView(
when (confirming) {
is AsyncAction.ConfirmingCancellation -> {
SaveChangesDialog(
onSubmitClick = { state.eventSink(ChangeRolesEvent.Exit) },
onDismiss = { state.eventSink(ChangeRolesEvent.CloseDialog) }
onSaveClick = { state.eventSink(ChangeRolesEvent.Save) },
onDiscardClick = { state.eventSink(ChangeRolesEvent.Exit) },
onDismiss = { state.eventSink(ChangeRolesEvent.CloseDialog) },
)
}
is ConfirmingModifyingOwners -> {