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 8c4de1af33..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 @@ -36,7 +36,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 @@ -49,13 +48,11 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.features.createroom.impl.R import io.element.android.features.createroom.impl.components.RoomPrivacyOption -import io.element.android.libraries.architecture.Async import io.element.android.libraries.designsystem.components.LabelledTextField -import io.element.android.libraries.designsystem.components.ProgressDialog +import io.element.android.libraries.designsystem.components.async.AsyncView import io.element.android.libraries.designsystem.components.button.BackButton -import io.element.android.libraries.designsystem.components.dialogs.RetryDialog -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 @@ -84,12 +81,6 @@ fun ConfigureRoomView( initialValue = ModalBottomSheetValue.Hidden, ) - if (state.createRoomAction is Async.Success) { - LaunchedEffect(state.createRoomAction) { - onRoomCreated(state.createRoomAction.data) - } - } - fun onAvatarClicked() { focusManager.clearFocus() coroutineScope.launch { @@ -158,21 +149,14 @@ fun ConfigureRoomView( onActionSelected = { state.eventSink(ConfigureRoomEvents.HandleAvatarAction(it)) } ) - when (state.createRoomAction) { - is Async.Loading -> { - ProgressDialog(text = stringResource(CommonStrings.common_creating_room)) - } - - is Async.Failure -> { - RetryDialog( - content = stringResource(R.string.screen_create_room_error_creating_room), - onDismiss = { state.eventSink(ConfigureRoomEvents.CancelCreateRoom) }, - onRetry = { state.eventSink(ConfigureRoomEvents.CreateRoom(state.config)) }, - ) - } - - else -> Unit - } + AsyncView( + async = state.createRoomAction, + progressText = stringResource(CommonStrings.common_creating_room), + onSuccess = { onRoomCreated(it) }, + errorMessage = { stringResource(R.string.screen_create_room_error_creating_room) }, + onRetry = { state.eventSink(ConfigureRoomEvents.CreateRoom(state.config)) }, + onErrorDismiss = { state.eventSink(ConfigureRoomEvents.CancelCreateRoom) }, + ) PermissionsView( state = state.cameraPermissionState, 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 452efa2b85..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 @@ -30,7 +30,6 @@ import androidx.compose.foundation.layout.size import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -38,12 +37,10 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.features.createroom.impl.R import io.element.android.features.createroom.impl.components.UserListView -import io.element.android.libraries.architecture.Async -import io.element.android.libraries.designsystem.components.ProgressDialog +import io.element.android.libraries.designsystem.components.async.AsyncView import io.element.android.libraries.designsystem.components.button.BackButton -import io.element.android.libraries.designsystem.components.dialogs.RetryDialog -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.Icon import io.element.android.libraries.designsystem.theme.components.Scaffold @@ -64,12 +61,6 @@ fun CreateRoomRootView( onOpenDM: (RoomId) -> Unit = {}, onInviteFriendsClicked: () -> Unit = {}, ) { - if (state.startDmAction is Async.Success) { - LaunchedEffect(state.startDmAction) { - onOpenDM(state.startDmAction.data) - } - } - Scaffold( modifier = modifier.fillMaxWidth(), topBar = { @@ -102,26 +93,19 @@ fun CreateRoomRootView( } } - when (state.startDmAction) { - is Async.Loading -> { - ProgressDialog(text = stringResource(id = CommonStrings.common_starting_chat)) - } - - is Async.Failure -> { - RetryDialog( - content = stringResource(id = R.string.screen_start_chat_error_starting_chat), - onDismiss = { state.eventSink(CreateRoomRootEvents.CancelStartDM) }, - onRetry = { - state.userListState.selectedUsers.firstOrNull() - ?.let { state.eventSink(CreateRoomRootEvents.StartDM(it)) } - // Cancel start DM if there is no more selected user (should not happen) - ?: state.eventSink(CreateRoomRootEvents.CancelStartDM) - }, - ) - } - - else -> Unit - } + AsyncView( + async = state.startDmAction, + progressText = stringResource(CommonStrings.common_starting_chat), + onSuccess = { onOpenDM(it) }, + errorMessage = { stringResource(R.string.screen_start_chat_error_starting_chat) }, + onRetry = { + state.userListState.selectedUsers.firstOrNull() + ?.let { state.eventSink(CreateRoomRootEvents.StartDM(it)) } + // Cancel start DM if there is no more selected user (should not happen) + ?: state.eventSink(CreateRoomRootEvents.CancelStartDM) + }, + onErrorDismiss = { state.eventSink(CreateRoomRootEvents.CancelStartDM) }, + ) } @OptIn(ExperimentalMaterial3Api::class) diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcView.kt index 33c7a8da57..66e3b31496 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcView.kt @@ -25,17 +25,14 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.viewinterop.AndroidView import io.element.android.features.login.impl.oidc.OidcUrlParser -import io.element.android.libraries.architecture.Async import io.element.android.libraries.core.bool.orFalse -import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog -import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.components.async.AsyncView import io.element.android.libraries.designsystem.preview.ElementPreview -import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator +import io.element.android.libraries.designsystem.preview.PreviewsDayNight @Composable fun OidcView( @@ -79,21 +76,11 @@ fun OidcView( } ) - when (state.requestState) { - Async.Uninitialized -> Unit - is Async.Failure -> { - ErrorDialog( - content = state.requestState.error.toString(), - onDismiss = { state.eventSink(OidcEvents.ClearError) } - ) - } - is Async.Loading -> { - CircularProgressIndicator( - modifier = Modifier.align(Alignment.Center) - ) - } - is Async.Success -> onNavigateBack() - } + AsyncView( + async = state.requestState, + onSuccess = { onNavigateBack() }, + onErrorDismiss = { state.eventSink(OidcEvents.ClearError) } + ) } } 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 3b6e46fd59..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 @@ -34,7 +34,6 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Switch import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource @@ -42,10 +41,10 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.libraries.architecture.Async +import io.element.android.libraries.designsystem.components.async.AsyncView 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.Button import io.element.android.libraries.designsystem.theme.components.OutlinedTextField @@ -64,21 +63,13 @@ fun ReportMessageView( ) { val focusManager = LocalFocusManager.current val isSending = state.result is Async.Loading - when (state.result) { - is Async.Success -> { - LaunchedEffect(state.result) { - onBackClicked() - } - return - } - is Async.Failure -> { - ErrorDialog( - content = stringResource(CommonStrings.error_unknown), - onDismiss = { state.eventSink(ReportMessageEvents.ClearError) } - ) - } - else -> Unit - } + AsyncView( + async = state.result, + showProgressDialog = false, + onSuccess = { onBackClicked() }, + errorMessage = { stringResource(CommonStrings.error_unknown) }, + onErrorDismiss = { state.eventSink(ReportMessageEvents.ClearError) } + ) Scaffold( topBar = { 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 a1d248c1fd..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 @@ -24,9 +24,8 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.lifecycle.Lifecycle import io.element.android.libraries.androidutils.system.startNotificationSettingsIntent -import io.element.android.libraries.architecture.Async import io.element.android.libraries.designsystem.atomic.molecules.DialogLikeBannerMolecule -import io.element.android.libraries.designsystem.components.ProgressDialog +import io.element.android.libraries.designsystem.components.async.AsyncView import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory import io.element.android.libraries.designsystem.components.preferences.PreferencePage @@ -79,19 +78,12 @@ fun NotificationSettingsView( // onCallsNotificationsChanged = { state.eventSink(NotificationSettingsEvents.SetCallNotificationsEnabled(it)) }, ) } - when (state.changeNotificationSettingAction) { - is Async.Loading -> { - ProgressDialog() - } - is Async.Failure -> { - ErrorDialog( - title = stringResource(CommonStrings.dialog_title_error), - content = stringResource(CommonStrings.screen_notification_settings_edit_failed_updating_default_mode), - onDismiss = { state.eventSink(NotificationSettingsEvents.ClearNotificationChangeError) }, - ) - } - else -> Unit - } + AsyncView( + async = state.changeNotificationSettingAction, + 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 94f5a6b053..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 @@ -22,20 +22,18 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource 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.async.AsyncView import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize -import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory +import io.element.android.libraries.designsystem.components.preferences.PreferencePage import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.ListItem import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.designsystem.components.preferences.PreferencePage -import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.ui.strings.CommonStrings @@ -46,11 +44,10 @@ import io.element.android.libraries.ui.strings.CommonStrings @Composable fun EditDefaultNotificationSettingView( state: EditDefaultNotificationSettingState, - openRoomNotificationSettings:(roomId: RoomId) -> Unit, + openRoomNotificationSettings: (roomId: RoomId) -> Unit, onBackPressed: () -> Unit, modifier: Modifier = Modifier, ) { - val title = if (state.isOneToOne) { CommonStrings.screen_notification_settings_direct_chats } else { @@ -118,21 +115,15 @@ fun EditDefaultNotificationSettingView( } } } - when (state.changeNotificationSettingAction) { - is Async.Loading -> { - ProgressDialog() - } - is Async.Failure -> { - ErrorDialog( - title = stringResource(CommonStrings.dialog_title_error), - content = stringResource(CommonStrings.screen_notification_settings_edit_failed_updating_default_mode), - onDismiss = { state.eventSink(EditDefaultNotificationSettingStateEvents.ClearError) }, - ) - } - else -> Unit - } + AsyncView( + async = state.changeNotificationSettingAction, + errorMessage = { stringResource(CommonStrings.screen_notification_settings_edit_failed_updating_default_mode) }, + onErrorDismiss = { state.eventSink(EditDefaultNotificationSettingStateEvents.ClearError) }, + onSuccess = {}, + ) } } + @PreviewsDayNight @Composable internal fun EditDefaultNotificationSettingViewPreview( 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/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt index d886819690..2cbb54cdad 100644 --- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt +++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt @@ -23,7 +23,6 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment @@ -39,16 +38,15 @@ import coil.compose.AsyncImage import coil.request.ImageRequest import io.element.android.features.rageshake.impl.R import io.element.android.libraries.architecture.Async -import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog +import io.element.android.libraries.designsystem.components.async.AsyncView import io.element.android.libraries.designsystem.components.form.textFieldState +import io.element.android.libraries.designsystem.components.preferences.PreferencePage import io.element.android.libraries.designsystem.components.preferences.PreferenceRow import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch -import io.element.android.libraries.designsystem.components.preferences.PreferencePage -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.preview.debugPlaceholderBackground import io.element.android.libraries.designsystem.theme.components.Button -import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator import io.element.android.libraries.designsystem.theme.components.OutlinedTextField import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.utils.LogCompositions @@ -63,13 +61,6 @@ fun BugReportView( ) { LogCompositions(tag = "Rageshake", msg = "Root") val eventSink = state.eventSink - if (state.sending is Async.Success) { - LaunchedEffect(state.sending) { - eventSink(BugReportEvents.ResetAll) - onDone() - } - return - } Box(modifier = modifier) { PreferencePage( @@ -151,6 +142,7 @@ fun BugReportView( text = stringResource(id = CommonStrings.action_send), onClick = { eventSink(BugReportEvents.SendBugReport) }, enabled = state.submitEnabled, + showProgress = state.sending.isLoading(), modifier = Modifier .fillMaxWidth() .padding(top = 24.dp, bottom = 16.dp) @@ -158,19 +150,15 @@ fun BugReportView( } } - when (state.sending) { - is Async.Loading -> { - // Indeterminate indicator, to avoid the freeze effect if the connection takes time to initialize. - CircularProgressIndicator( - modifier = Modifier.align(Alignment.Center) - ) - } - is Async.Failure -> ErrorDialog( - content = state.sending.error.toString(), - onDismiss = { state.eventSink(BugReportEvents.ClearError) } - ) - else -> Unit - } + AsyncView( + async = state.sending, + showProgressDialog = false, + onSuccess = { + eventSink(BugReportEvents.ResetAll) + onDone() + }, + onErrorDismiss = { eventSink(BugReportEvents.ClearError) }, + ) } } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt index 3d0de05d34..90ee19c115 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt @@ -36,7 +36,6 @@ import androidx.compose.material.rememberModalBottomSheetState import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusManager @@ -47,14 +46,12 @@ import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.features.roomdetails.impl.R -import io.element.android.libraries.architecture.Async import io.element.android.libraries.designsystem.components.LabelledTextField -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 @@ -174,26 +171,13 @@ fun RoomDetailsEditView( onActionSelected = { state.eventSink(RoomDetailsEditEvents.HandleAvatarAction(it)) } ) - when (state.saveAction) { - is Async.Loading -> { - ProgressDialog(text = stringResource(R.string.screen_room_details_updating_room)) - } - - is Async.Failure -> { - ErrorDialog( - content = stringResource(R.string.screen_room_details_edition_error), - onDismiss = { state.eventSink(RoomDetailsEditEvents.CancelSaveChanges) }, - ) - } - - is Async.Success -> { - LaunchedEffect(state.saveAction) { - onRoomEdited() - } - } - - else -> Unit - } + AsyncView( + async = state.saveAction, + progressText = stringResource(R.string.screen_room_details_updating_room), + onSuccess = { onRoomEdited() }, + errorMessage = { stringResource(R.string.screen_room_details_edition_error) }, + onErrorDismiss = { state.eventSink(RoomDetailsEditEvents.CancelSaveChanges) } + ) PermissionsView( state = state.cameraPermissionState, diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsView.kt index 0b9a1fd5f9..96372c0e65 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsView.kt @@ -32,9 +32,8 @@ 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.roomdetails.impl.R -import io.element.android.libraries.architecture.Async import io.element.android.libraries.core.bool.orTrue -import io.element.android.libraries.designsystem.components.ProgressDialog +import io.element.android.libraries.designsystem.components.async.AsyncView import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch @@ -49,7 +48,6 @@ import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.ui.strings.CommonStrings - @Composable fun RoomNotificationSettingsView( state: RoomNotificationSettingsState, @@ -57,7 +55,7 @@ fun RoomNotificationSettingsView( onShowGlobalNotifications: () -> Unit = {}, onBackPressed: () -> Unit = {}, ) { - if(state.showUserDefinedSettingStyle) { + if (state.showUserDefinedSettingStyle) { UserDefinedRoomNotificationSettingsView( state = state, modifier = modifier, @@ -117,7 +115,7 @@ private fun RoomSpecificNotificationSettingsView( ClickableText( text = text, onClick = { - onShowGlobalNotifications() + onShowGlobalNotifications() }, modifier = Modifier .padding(start = 16.dp, bottom = 16.dp, end = 16.dp), @@ -127,7 +125,7 @@ private fun RoomSpecificNotificationSettingsView( textAlign = TextAlign.Center, ) ) - if(state.defaultRoomNotificationMode != null){ + if (state.defaultRoomNotificationMode != null) { val defaultModeTitle = when (state.defaultRoomNotificationMode) { RoomNotificationMode.ALL_MESSAGES -> stringResource(id = R.string.screen_room_notification_settings_mode_all_messages) RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> { @@ -150,29 +148,24 @@ private fun RoomSpecificNotificationSettingsView( enabled = !state.displayIsDefault.orTrue(), onOptionSelected = { state.eventSink(RoomNotificationSettingsEvents.RoomNotificationModeChanged(it.mode)) - },) + }, + ) } } - when (state.setNotificationSettingAction) { - is Async.Loading -> { - ProgressDialog() - } - is Async.Failure -> { - ShowChangeNotificationSettingError(state, RoomNotificationSettingsEvents.ClearSetNotificationError) - } - else -> Unit - } + AsyncView( + async = state.setNotificationSettingAction, + onSuccess = {}, + errorMessage = { stringResource(CommonStrings.screen_notification_settings_edit_failed_updating_default_mode) }, + onErrorDismiss = { state.eventSink(RoomNotificationSettingsEvents.ClearSetNotificationError) }, + ) - when (state.restoreDefaultAction) { - is Async.Loading -> { - ProgressDialog() - } - is Async.Failure -> { - ShowChangeNotificationSettingError(state, RoomNotificationSettingsEvents.ClearRestoreDefaultError) - } - else -> Unit - } + AsyncView( + async = state.restoreDefaultAction, + onSuccess = {}, + errorMessage = { stringResource(CommonStrings.screen_notification_settings_edit_failed_updating_default_mode) }, + onErrorDismiss = { state.eventSink(RoomNotificationSettingsEvents.ClearRestoreDefaultError) }, + ) } } } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/ShowChangeNotificationSettingError.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/ShowChangeNotificationSettingError.kt deleted file mode 100644 index 4b99976988..0000000000 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/ShowChangeNotificationSettingError.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2023 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.element.android.features.roomdetails.impl.notificationsettings - -import androidx.compose.runtime.Composable -import androidx.compose.ui.res.stringResource -import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog -import io.element.android.libraries.ui.strings.CommonStrings - -@Composable -fun ShowChangeNotificationSettingError(state: RoomNotificationSettingsState, event: RoomNotificationSettingsEvents) { - ErrorDialog( - title = stringResource(CommonStrings.dialog_title_error), - content = stringResource(CommonStrings.screen_notification_settings_edit_failed_updating_default_mode), - onDismiss = { state.eventSink(event) }, - ) -} diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsView.kt index 6afde5bbf9..88a4b8a0a1 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsView.kt @@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource @@ -32,9 +31,8 @@ import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.features.roomdetails.impl.R -import io.element.android.libraries.architecture.Async import io.element.android.libraries.core.bool.orTrue -import io.element.android.libraries.designsystem.components.ProgressDialog +import io.element.android.libraries.designsystem.components.async.AsyncView import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.preferences.PreferenceText import io.element.android.libraries.designsystem.preview.ElementPreview @@ -43,6 +41,7 @@ import io.element.android.libraries.designsystem.theme.components.Scaffold import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.designsystem.utils.CommonDrawables +import io.element.android.libraries.ui.strings.CommonStrings @Composable fun UserDefinedRoomNotificationSettingsView( @@ -86,30 +85,19 @@ fun UserDefinedRoomNotificationSettingsView( } ) - when (state.setNotificationSettingAction) { - is Async.Loading -> { - ProgressDialog() - } - is Async.Failure -> { - ShowChangeNotificationSettingError(state, RoomNotificationSettingsEvents.ClearSetNotificationError) - } - else -> Unit - } + AsyncView( + async = state.setNotificationSettingAction, + onSuccess = {}, + errorMessage = { stringResource(CommonStrings.screen_notification_settings_edit_failed_updating_default_mode) }, + onErrorDismiss = { state.eventSink(RoomNotificationSettingsEvents.ClearSetNotificationError) }, + ) - when (state.restoreDefaultAction) { - is Async.Loading -> { - ProgressDialog() - } - is Async.Failure -> { - ShowChangeNotificationSettingError(state, RoomNotificationSettingsEvents.ClearRestoreDefaultError) - } - is Async.Success -> { - LaunchedEffect(state.restoreDefaultAction) { - onBackPressed() - } - } - else -> Unit - } + AsyncView( + async = state.restoreDefaultAction, + onSuccess = { onBackPressed() }, + errorMessage = { stringResource(CommonStrings.screen_notification_settings_edit_failed_updating_default_mode) }, + onErrorDismiss = { state.eventSink(RoomNotificationSettingsEvents.ClearRestoreDefaultError) }, + ) } } } diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt index c3e20e2312..b40305e0d5 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt @@ -20,19 +20,17 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.features.securebackup.impl.R import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyView -import io.element.android.libraries.architecture.Async import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage +import io.element.android.libraries.designsystem.components.async.AsyncView 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.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Button @@ -48,19 +46,12 @@ fun SecureBackupEnterRecoveryKeyView( onBackClicked: () -> Unit, modifier: Modifier = Modifier, ) { - when (state.submitAction) { - Async.Uninitialized -> Unit - is Async.Failure -> ErrorDialog( - content = state.submitAction.error.message ?: state.submitAction.error.toString(), - onDismiss = { - state.eventSink(SecureBackupEnterRecoveryKeyEvents.ClearDialog) - } - ) - is Async.Loading -> Unit - is Async.Success -> LaunchedEffect(state.submitAction) { - onDone() - } - } + AsyncView( + async = state.submitAction, + onSuccess = { onDone() }, + showProgressDialog = false, + onErrorDismiss = { state.eventSink(SecureBackupEnterRecoveryKeyEvents.ClearDialog) }, + ) HeaderFooterPage( modifier = modifier, diff --git a/libraries/designsystem/build.gradle.kts b/libraries/designsystem/build.gradle.kts index f0d9d0bd53..1a1e44366b 100644 --- a/libraries/designsystem/build.gradle.kts +++ b/libraries/designsystem/build.gradle.kts @@ -39,6 +39,7 @@ android { // Should not be there, but this is a POC implementation(libs.coil.compose) implementation(libs.vanniktech.blurhash) + implementation(projects.libraries.architecture) implementation(projects.libraries.testtags) implementation(projects.libraries.uiStrings) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncProvider.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncProvider.kt new file mode 100644 index 0000000000..028de2d57b --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncProvider.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.components.async + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.architecture.Async + +open class AsyncProvider : PreviewParameterProvider> { + override val values: Sequence> + get() = sequenceOf( + Async.Uninitialized, + Async.Loading(), + Async.Failure(Exception("An error occurred")), + Async.Success(Unit), + ) +} 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 new file mode 100644 index 0000000000..d19dc08c6a --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncView.kt @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.components.async + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +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 + +/** + * 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 [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]. + */ +@Composable +fun AsyncView( + async: Async, + onSuccess: (T) -> Unit, + onErrorDismiss: () -> Unit, + showProgressDialog: Boolean = true, + progressText: String? = null, + errorTitle: @Composable (Throwable) -> String = { ErrorDialogDefaults.title }, + errorMessage: @Composable (Throwable) -> String = { it.message ?: it.toString() }, + onRetry: (() -> Unit)? = null, +) { + AsyncView( + async = async, + onSuccess = onSuccess, + onErrorDismiss = onErrorDismiss, + progressDialog = { + if (showProgressDialog) { + AsyncViewDefaults.ProgressDialog(progressText) + } + }, + errorTitle = errorTitle, + errorMessage = errorMessage, + onRetry = onRetry, + ) +} + +@Composable +fun AsyncView( + async: Async, + onSuccess: (T) -> Unit, + onErrorDismiss: () -> Unit, + progressDialog: @Composable () -> Unit = { AsyncViewDefaults.ProgressDialog() }, + 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 -> progressDialog() + is Async.Failure -> { + if (onRetry == null) { + ErrorDialog( + title = errorTitle(async.error), + content = errorMessage(async.error), + onDismiss = onErrorDismiss + ) + } else { + RetryDialog( + title = errorTitle(async.error), + content = errorMessage(async.error), + onDismiss = onErrorDismiss, + onRetry = onRetry, + ) + } + } + is Async.Success -> { + LaunchedEffect(async) { + onSuccess(async.data) + } + } + } +} + +object AsyncViewDefaults { + @Composable + fun ProgressDialog(progressText: String? = null) { + ProgressDialog( + text = progressText, + ) + } +} + +@PreviewsDayNight +@Composable +internal fun AsyncViewPreview( + @PreviewParameter(AsyncProvider::class) async: Async, +) = ElementPreview { + AsyncView( + async = async, + onSuccess = {}, + onErrorDismiss = {}, + ) +} diff --git a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt index 64ca2e899b..d906063ae3 100644 --- a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt +++ b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt @@ -55,6 +55,8 @@ class KonsistClassNameTest { val providedType = it.text .substringBefore(">") .substringAfter("<") + // Get the substring before the first '<' to remove the generic type + .substringBefore("<") .removeSuffix("?") .replace(".", "") it.name.endsWith("Provider") && it.name.contains(providedType) diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.oidc.webview_OidcView_null_OidcView-Day-3_4_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.oidc.webview_OidcView_null_OidcView-Day-3_4_null_1,NEXUS_5,1.0,en].png index fae021d50a..77b40fbae8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.oidc.webview_OidcView_null_OidcView-Day-3_4_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.oidc.webview_OidcView_null_OidcView-Day-3_4_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e130fb7792bd1569ed9e7f2ac0e3b506925f6ce5ff146416296c1cbfccf4614d -size 8209 +oid sha256:b681059a38c6f13a8528a083ba4c53e05fc24c39ce36010eb39c81c641e1126e +size 11585 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.oidc.webview_OidcView_null_OidcView-Night-3_5_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.oidc.webview_OidcView_null_OidcView-Night-3_5_null_1,NEXUS_5,1.0,en].png index 7444671dbf..c1b5ba9c87 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.oidc.webview_OidcView_null_OidcView-Night-3_5_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.oidc.webview_OidcView_null_OidcView-Night-3_5_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f6f3b4ab6e52a1c2bc0d73e94097008d03fc407c810ce5b86b9993e78e12b8c3 -size 8122 +oid sha256:550b9f37069061ca7e1244c94dafd0d2bdf09c789306a12354e0dfb584e34539 +size 9242 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_ReportMessageView_null_ReportMessageView-Day-7_7_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_ReportMessageView_null_ReportMessageView-Day-7_7_null_5,NEXUS_5,1.0,en].png index 665c8811ac..a806573632 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_ReportMessageView_null_ReportMessageView-Day-7_7_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_ReportMessageView_null_ReportMessageView-Day-7_7_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb0d3bfcfd75cbd75fd9270ff1dc27090e5dbac79ca8db8a46d91a4c12bc966b -size 4457 +oid sha256:b09b37b87bc25d3e5e46cbafbe468cab3d025fc855fc531fc30a08f4b872520a +size 46911 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_ReportMessageView_null_ReportMessageView-Night-7_8_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_ReportMessageView_null_ReportMessageView-Night-7_8_null_5,NEXUS_5,1.0,en].png index fae8a6fca3..ae79ef4871 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_ReportMessageView_null_ReportMessageView-Night-7_8_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_ReportMessageView_null_ReportMessageView-Night-7_8_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8c89ac73df77c2bccb0c2aa80cee1420f78e7d07f0eda89a90bffef55e8cf753 -size 4464 +oid sha256:692b4493554c2a11b278b8c0421ce3463e883ee9944209bd0f8fc4dc4d325446 +size 44443 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Day-0_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Day-0_0_null_2,NEXUS_5,1.0,en].png index f328f044b8..aa132627e5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Day-0_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Day-0_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bdc1ab359d66c5017079bd789b687b3a36adf41c14fb12ceeb8aa55660253851 -size 60281 +oid sha256:332e7a7baa12fb54fed4ad99f53470a96182e6059f3f24631ef9c5a7ed9c9f54 +size 59420 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Day-0_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Day-0_0_null_3,NEXUS_5,1.0,en].png index 665c8811ac..5f5be1fdc5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Day-0_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Day-0_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb0d3bfcfd75cbd75fd9270ff1dc27090e5dbac79ca8db8a46d91a4c12bc966b -size 4457 +oid sha256:bf178a51be45cfd5fee676628ae3192374c1bc873e6eef726053ae593974aafe +size 68108 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Night-0_1_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Night-0_1_null_2,NEXUS_5,1.0,en].png index ec1dc267b7..cda48a2eff 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Night-0_1_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Night-0_1_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ce770961f7eae4f6e9e396f7102761a67d049b8f65958d57f75c3b3a33be084 -size 55548 +oid sha256:e93d40807105a64a933180a71a73c661c4b792f5a008af7ada5fc8fd80a1446b +size 54960 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Night-0_1_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Night-0_1_null_3,NEXUS_5,1.0,en].png index fae8a6fca3..adc80daf5f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Night-0_1_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.rageshake.impl.bugreport_BugReportView_null_BugReportView-Night-0_1_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8c89ac73df77c2bccb0c2aa80cee1420f78e7d07f0eda89a90bffef55e8cf753 -size 4464 +oid sha256:310bd5d524d61cbc3b8237811c8d6623a6fb1046bb8a9823ff5173c2f2b3c862 +size 65218 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..665c8811ac --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb0d3bfcfd75cbd75fd9270ff1dc27090e5dbac79ca8db8a46d91a4c12bc966b +size 4457 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_1,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..4e44ed5288 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_1,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf70dc030f96b929ba3817694a624de715b82719117fc75720c4e3ff8a8188c8 +size 9962 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_2,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..9fa8bd98b2 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_2,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:083ec0dc6c816f2e782d1f502d2c39e78a8f01052a4507fd3ae83fec059d5065 +size 12921 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_3,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..665c8811ac --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_3,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb0d3bfcfd75cbd75fd9270ff1dc27090e5dbac79ca8db8a46d91a4c12bc966b +size 4457 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..fae8a6fca3 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c89ac73df77c2bccb0c2aa80cee1420f78e7d07f0eda89a90bffef55e8cf753 +size 4464 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_1,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..825f2f46d5 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_1,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8b6b2f2e2c03e7927ccb93d4fa8e914f7a3a19f4526cda8237e324dda3d9d3f +size 7548 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_2,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..e034e429e0 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_2,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2bd73005dfe9470509aa4bf79fae3c9f6a25b2bc8bdb71475c71dafc0d7e8f7a +size 10196 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_3,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..fae8a6fca3 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_3,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c89ac73df77c2bccb0c2aa80cee1420f78e7d07f0eda89a90bffef55e8cf753 +size 4464