diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt index 5792220917..d12a6076b5 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt @@ -149,12 +149,11 @@ fun ConfigureRoomView( onActionSelected = { state.eventSink(ConfigureRoomEvents.HandleAvatarAction(it)) } ) - val errorMessage = stringResource(R.string.screen_create_room_error_creating_room) AsyncView( async = state.createRoomAction, progressText = stringResource(CommonStrings.common_creating_room), onSuccess = { onRoomCreated(it) }, - errorTransform = { errorMessage }, + errorMessage = { stringResource(R.string.screen_create_room_error_creating_room) }, onRetry = { state.eventSink(ConfigureRoomEvents.CreateRoom(state.config)) }, onErrorDismiss = { state.eventSink(ConfigureRoomEvents.CancelCreateRoom) }, ) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt index 34219b4498..6902a45378 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt @@ -93,12 +93,11 @@ fun CreateRoomRootView( } } - val errorMessage = stringResource(R.string.screen_start_chat_error_starting_chat) AsyncView( async = state.startDmAction, progressText = stringResource(CommonStrings.common_starting_chat), onSuccess = { onOpenDM(it) }, - errorTransform = { errorMessage }, + errorMessage = { stringResource(R.string.screen_start_chat_error_starting_chat) }, onRetry = { state.userListState.selectedUsers.firstOrNull() ?.let { state.eventSink(CreateRoomRootEvents.StartDM(it)) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt index bf71d19aca..d75c8f45c6 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt @@ -63,12 +63,11 @@ fun ReportMessageView( ) { val focusManager = LocalFocusManager.current val isSending = state.result is Async.Loading - val errorMessage = stringResource(CommonStrings.error_unknown) AsyncView( async = state.result, showProgressDialog = false, onSuccess = { onBackClicked() }, - errorTransform = { errorMessage }, + errorMessage = { stringResource(CommonStrings.error_unknown) }, onErrorDismiss = { state.eventSink(ReportMessageEvents.ClearError) } ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt index ac027bfb95..f93ecad3fd 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt @@ -78,10 +78,9 @@ fun NotificationSettingsView( // onCallsNotificationsChanged = { state.eventSink(NotificationSettingsEvents.SetCallNotificationsEnabled(it)) }, ) } - val errorMessage = stringResource(CommonStrings.screen_notification_settings_edit_failed_updating_default_mode) AsyncView( async = state.changeNotificationSettingAction, - errorTransform = { errorMessage }, + errorMessage = { stringResource(CommonStrings.screen_notification_settings_edit_failed_updating_default_mode) }, onErrorDismiss = { state.eventSink(NotificationSettingsEvents.ClearNotificationChangeError) }, onSuccess = {}, ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt index d00fbc70a0..dbbd90791b 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt @@ -115,10 +115,9 @@ fun EditDefaultNotificationSettingView( } } } - val errorMessage = stringResource(CommonStrings.screen_notification_settings_edit_failed_updating_default_mode) AsyncView( async = state.changeNotificationSettingAction, - errorTransform = { errorMessage }, + errorMessage = { stringResource(CommonStrings.screen_notification_settings_edit_failed_updating_default_mode) }, onErrorDismiss = { state.eventSink(EditDefaultNotificationSettingStateEvents.ClearError) }, onSuccess = {}, ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt index 760e08261d..9031a2e20f 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt @@ -31,7 +31,6 @@ import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material.rememberModalBottomSheetState import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -43,14 +42,12 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.features.preferences.impl.R -import io.element.android.libraries.architecture.Async import io.element.android.libraries.designsystem.components.LabelledOutlinedTextField -import io.element.android.libraries.designsystem.components.ProgressDialog +import io.element.android.libraries.designsystem.components.async.AsyncView import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.button.BackButton -import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog -import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.aliasScreenTitle import io.element.android.libraries.designsystem.theme.components.Scaffold import io.element.android.libraries.designsystem.theme.components.Text @@ -150,24 +147,14 @@ fun EditUserProfileView( onActionSelected = { state.eventSink(EditUserProfileEvents.HandleAvatarAction(it)) } ) - when (state.saveAction) { - is Async.Loading -> { - ProgressDialog(text = stringResource(R.string.screen_edit_profile_updating_details)) - } - is Async.Failure -> { - ErrorDialog( - title = stringResource(R.string.screen_edit_profile_error_title), - content = stringResource(R.string.screen_edit_profile_error), - onDismiss = { state.eventSink(EditUserProfileEvents.CancelSaveChanges) }, - ) - } - is Async.Success -> { - LaunchedEffect(state.saveAction) { - onProfileEdited() - } - } - else -> Unit - } + AsyncView( + async = state.saveAction, + progressText = stringResource(R.string.screen_edit_profile_updating_details), + onSuccess = { onProfileEdited() }, + errorTitle = { stringResource(R.string.screen_edit_profile_error_title) }, + errorMessage = { stringResource(R.string.screen_edit_profile_error) }, + onErrorDismiss = { state.eventSink(EditUserProfileEvents.CancelSaveChanges) }, + ) } PermissionsView( state = state.cameraPermissionState, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncView.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncView.kt index eeee81e07f..5ca7a5b650 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncView.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncView.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import io.element.android.libraries.architecture.Async import io.element.android.libraries.designsystem.components.ProgressDialog import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog +import io.element.android.libraries.designsystem.components.dialogs.ErrorDialogDefaults import io.element.android.libraries.designsystem.components.dialogs.RetryDialog import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -30,7 +31,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight /** * Render an Async object. * - If Success, invoke the callback [onSuccess], only once. - * - If Failure, display a dialog with the error, which can be transformed, using [errorTransform]. When + * - If Failure, display a dialog with the error, which can be transformed, using [errorMessage]. When * closed, [onErrorDismiss] will be invoked. If [onRetry] is not null, a retry button will be displayed. * - When loading, display a loading dialog, if [showProgressDialog] is true, with on optional [progressText]. */ @@ -42,9 +43,11 @@ fun AsyncView( modifier: Modifier = Modifier, showProgressDialog: Boolean = true, progressText: String? = null, - errorTransform: (Throwable) -> String = { it.message ?: it.toString() }, + errorTitle: @Composable (Throwable) -> String = { ErrorDialogDefaults.title }, + errorMessage: @Composable (Throwable) -> String = { it.message ?: it.toString() }, onRetry: (() -> Unit)? = null, ) { + when (async) { Async.Uninitialized -> Unit is Async.Loading -> { @@ -59,13 +62,15 @@ fun AsyncView( if (onRetry == null) { ErrorDialog( modifier = modifier, - content = errorTransform(async.error), + title = errorTitle(async.error), + content = errorMessage(async.error), onDismiss = onErrorDismiss ) } else { RetryDialog( modifier = modifier, - content = errorTransform(async.error), + title = errorTitle(async.error), + content = errorMessage(async.error), onDismiss = onErrorDismiss, onRetry = onRetry, )