From e42005fc52c7da63f236217fdb781a62b399f3fc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 4 Jan 2024 16:49:22 +0100 Subject: [PATCH] Rename AsyncView to AsyncActionView --- .../features/createroom/api/StartDMAction.kt | 4 +- .../createroom/impl/DefaultStartDMAction.kt | 10 +-- .../configureroom/ConfigureRoomPresenter.kt | 10 +-- .../impl/configureroom/ConfigureRoomState.kt | 6 +- .../ConfigureRoomStateProvider.kt | 4 +- .../impl/configureroom/ConfigureRoomView.kt | 4 +- .../impl/root/CreateRoomRootPresenter.kt | 6 +- .../impl/root/CreateRoomRootState.kt | 4 +- .../impl/root/CreateRoomRootStateProvider.kt | 8 +-- .../impl/root/CreateRoomRootView.kt | 4 +- .../impl/DefaultStartDMActionTests.kt | 14 ++-- .../ConfigureRoomPresenterTests.kt | 32 ++++----- .../impl/root/CreateRoomRootPresenterTests.kt | 15 ++--- .../createroom/test/FakeStartDMAction.kt | 10 +-- .../login/impl/oidc/webview/OidcPresenter.kt | 18 ++--- .../login/impl/oidc/webview/OidcState.kt | 4 +- .../impl/oidc/webview/OidcStateProvider.kt | 6 +- .../login/impl/oidc/webview/OidcView.kt | 4 +- .../impl/oidc/webview/OidcPresenterTest.kt | 24 +++---- .../impl/report/ReportMessagePresenter.kt | 8 +-- .../impl/report/ReportMessageState.kt | 4 +- .../impl/report/ReportMessageStateProvider.kt | 10 +-- .../messages/impl/report/ReportMessageView.kt | 7 +- .../report/ReportMessagePresenterTests.kt | 18 ++--- .../NotificationSettingsPresenter.kt | 14 ++-- .../NotificationSettingsState.kt | 8 +-- .../NotificationSettingsStateProvider.kt | 8 +-- .../notifications/NotificationSettingsView.kt | 4 +- ...EditDefaultNotificationSettingPresenter.kt | 12 ++-- .../EditDefaultNotificationSettingState.kt | 4 +- ...DefaultNotificationSettingStateProvider.kt | 10 +-- .../EditDefaultNotificationSettingView.kt | 4 +- .../editprofile/EditUserProfilePresenter.kt | 15 +++-- .../user/editprofile/EditUserProfileState.kt | 4 +- .../EditUserProfileStateProvider.kt | 4 +- .../user/editprofile/EditUserProfileView.kt | 4 +- .../EditUserProfilePresenterTest.kt | 14 ++-- .../impl/bugreport/BugReportPresenter.kt | 18 ++--- .../impl/bugreport/BugReportState.kt | 6 +- .../impl/bugreport/BugReportStateProvider.kt | 8 +-- .../rageshake/impl/bugreport/BugReportView.kt | 8 +-- .../impl/bugreport/BugReportPresenterTest.kt | 18 ++--- .../impl/edit/RoomDetailsEditPresenter.kt | 13 ++-- .../impl/edit/RoomDetailsEditState.kt | 4 +- .../impl/edit/RoomDetailsEditStateProvider.kt | 8 +-- .../impl/edit/RoomDetailsEditView.kt | 4 +- .../members/details/RoomMemberDetailsNode.kt | 3 +- .../details/RoomMemberDetailsPresenter.kt | 5 +- .../members/details/RoomMemberDetailsState.kt | 3 +- .../details/RoomMemberDetailsStateProvider.kt | 5 +- .../members/details/RoomMemberDetailsView.kt | 4 +- .../RoomNotificationSettingsPresenter.kt | 15 +++-- .../RoomNotificationSettingsState.kt | 5 +- .../RoomNotificationSettingsStateProvider.kt | 13 ++-- .../RoomNotificationSettingsView.kt | 6 +- ...edRoomNotificationSettingsStateProvider.kt | 5 +- ...UserDefinedRoomNotificationSettingsView.kt | 6 +- .../edit/RoomDetailsEditPresenterTest.kt | 14 ++-- .../RoomMemberDetailsPresenterTests.kt | 14 ++-- .../disable/SecureBackupDisablePresenter.kt | 8 +-- .../impl/disable/SecureBackupDisableState.kt | 4 +- .../SecureBackupDisableStateProvider.kt | 8 +-- .../impl/disable/SecureBackupDisableView.kt | 5 +- .../SecureBackupEnterRecoveryKeyPresenter.kt | 10 +-- .../SecureBackupEnterRecoveryKeyState.kt | 4 +- ...cureBackupEnterRecoveryKeyStateProvider.kt | 7 +- .../enter/SecureBackupEnterRecoveryKeyView.kt | 4 +- .../SecureBackupDisablePresenterTest.kt | 14 ++-- ...cureBackupEnterRecoveryKeyPresenterTest.kt | 14 ++-- ...syncProvider.kt => AsyncActionProvider.kt} | 15 +++-- .../{AsyncView.kt => AsyncActionView.kt} | 67 ++++++++++++++----- 71 files changed, 369 insertions(+), 315 deletions(-) rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/{AsyncProvider.kt => AsyncActionProvider.kt} (65%) rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/{AsyncView.kt => AsyncActionView.kt} (62%) diff --git a/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/StartDMAction.kt b/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/StartDMAction.kt index 4e20cea5d1..baacfa79dc 100644 --- a/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/StartDMAction.kt +++ b/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/StartDMAction.kt @@ -17,7 +17,7 @@ package io.element.android.features.createroom.api import androidx.compose.runtime.MutableState -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.UserId @@ -27,5 +27,5 @@ interface StartDMAction { * @param userId The user to start a DM with. * @param actionState The state to update with the result of the action. */ - suspend fun execute(userId: UserId, actionState: MutableState>) + suspend fun execute(userId: UserId, actionState: MutableState>) } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultStartDMAction.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultStartDMAction.kt index f129071824..c941c41958 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultStartDMAction.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultStartDMAction.kt @@ -20,7 +20,7 @@ import androidx.compose.runtime.MutableState import com.squareup.anvil.annotations.ContributesBinding import im.vector.app.features.analytics.plan.CreatedRoom import io.element.android.features.createroom.api.StartDMAction -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId @@ -36,17 +36,17 @@ class DefaultStartDMAction @Inject constructor( private val analyticsService: AnalyticsService, ) : StartDMAction { - override suspend fun execute(userId: UserId, actionState: MutableState>) { - actionState.value = AsyncData.Loading() + override suspend fun execute(userId: UserId, actionState: MutableState>) { + actionState.value = AsyncAction.Loading when (val result = matrixClient.startDM(userId)) { is StartDMResult.Success -> { if (result.isNew) { analyticsService.capture(CreatedRoom(isDM = true)) } - actionState.value = AsyncData.Success(result.roomId) + actionState.value = AsyncAction.Success(result.roomId) } is StartDMResult.Failure -> { - actionState.value = AsyncData.Failure(result.throwable) + actionState.value = AsyncAction.Failure(result.throwable) } } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index 46f6113780..6e077c6e50 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -29,7 +29,7 @@ import androidx.compose.runtime.rememberCoroutineScope import im.vector.app.features.analytics.plan.CreatedRoom import io.element.android.features.createroom.impl.CreateRoomConfig import io.element.android.features.createroom.impl.CreateRoomDataStore -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.core.mimetype.MimeTypes @@ -91,10 +91,10 @@ class ConfigureRoomPresenter @Inject constructor( } val localCoroutineScope = rememberCoroutineScope() - val createRoomAction: MutableState> = remember { mutableStateOf(AsyncData.Uninitialized) } + val createRoomAction: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } fun createRoom(config: CreateRoomConfig) { - createRoomAction.value = AsyncData.Uninitialized + createRoomAction.value = AsyncAction.Uninitialized localCoroutineScope.createRoom(config, createRoomAction) } @@ -118,7 +118,7 @@ class ConfigureRoomPresenter @Inject constructor( } } - ConfigureRoomEvents.CancelCreateRoom -> createRoomAction.value = AsyncData.Uninitialized + ConfigureRoomEvents.CancelCreateRoom -> createRoomAction.value = AsyncAction.Uninitialized } } @@ -133,7 +133,7 @@ class ConfigureRoomPresenter @Inject constructor( private fun CoroutineScope.createRoom( config: CreateRoomConfig, - createRoomAction: MutableState> + createRoomAction: MutableState> ) = launch { suspend { val avatarUrl = config.avatarUri?.let { uploadAvatar(it) } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt index 7b932db9b6..f275a0e217 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt @@ -16,17 +16,17 @@ package io.element.android.features.createroom.impl.configureroom -import io.element.android.libraries.matrix.ui.media.AvatarAction import io.element.android.features.createroom.impl.CreateRoomConfig -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.ui.media.AvatarAction import io.element.android.libraries.permissions.api.PermissionsState import kotlinx.collections.immutable.ImmutableList data class ConfigureRoomState( val config: CreateRoomConfig, val avatarActions: ImmutableList, - val createRoomAction: AsyncData, + val createRoomAction: AsyncAction, val cameraPermissionState: PermissionsState, val eventSink: (ConfigureRoomEvents) -> Unit ) { diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt index f5a665f25e..1065f746e0 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt @@ -19,7 +19,7 @@ package io.element.android.features.createroom.impl.configureroom import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.createroom.impl.CreateRoomConfig import io.element.android.features.createroom.impl.userlist.aListOfSelectedUsers -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.permissions.api.aPermissionsState import kotlinx.collections.immutable.persistentListOf @@ -41,7 +41,7 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider> = remember { mutableStateOf(AsyncData.Uninitialized) } + val startDmActionState: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } fun handleEvents(event: CreateRoomRootEvents) { when (event) { is CreateRoomRootEvents.StartDM -> localCoroutineScope.launch { startDMAction.execute(event.matrixUser.userId, startDmActionState) } - CreateRoomRootEvents.CancelStartDM -> startDmActionState.value = AsyncData.Uninitialized + CreateRoomRootEvents.CancelStartDM -> startDmActionState.value = AsyncAction.Uninitialized } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt index ad583e2cbf..185c08c131 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt @@ -17,12 +17,12 @@ package io.element.android.features.createroom.impl.root import io.element.android.features.createroom.impl.userlist.UserListState -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.RoomId data class CreateRoomRootState( val applicationName: String, val userListState: UserListState, - val startDmAction: AsyncData, + val startDmAction: AsyncAction, val eventSink: (CreateRoomRootEvents) -> Unit, ) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt index ceef8daa73..59980b7561 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt @@ -18,8 +18,8 @@ package io.element.android.features.createroom.impl.root import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.createroom.impl.userlist.aUserListState +import io.element.android.libraries.architecture.AsyncAction -import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.libraries.usersearch.api.UserSearchResult @@ -30,7 +30,7 @@ open class CreateRoomRootStateProvider : PreviewParameterProvider>(AsyncData.Uninitialized) + val state = mutableStateOf>(AsyncAction.Uninitialized) action.execute(A_USER_ID, state) - assertThat(state.value).isEqualTo(AsyncData.Success(A_ROOM_ID)) + assertThat(state.value).isEqualTo(AsyncAction.Success(A_ROOM_ID)) } @Test @@ -52,9 +52,9 @@ class DefaultStartDMActionTests { } val analyticsService = FakeAnalyticsService() val action = createStartDMAction(matrixClient, analyticsService) - val state = mutableStateOf>(AsyncData.Uninitialized) + val state = mutableStateOf>(AsyncAction.Uninitialized) action.execute(A_USER_ID, state) - assertThat(state.value).isEqualTo(AsyncData.Success(A_ROOM_ID)) + assertThat(state.value).isEqualTo(AsyncAction.Success(A_ROOM_ID)) assertThat(analyticsService.capturedEvents).containsExactly(CreatedRoom(isDM = true)) } @@ -65,9 +65,9 @@ class DefaultStartDMActionTests { givenCreateDmResult(Result.failure(A_THROWABLE)) } val action = createStartDMAction(matrixClient) - val state = mutableStateOf>(AsyncData.Uninitialized) + val state = mutableStateOf>(AsyncAction.Uninitialized) action.execute(A_USER_ID, state) - assertThat(state.value).isEqualTo(AsyncData.Failure(A_THROWABLE)) + assertThat(state.value).isEqualTo(AsyncAction.Failure(A_THROWABLE)) } private fun createStartDMAction( diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt index e0be429790..1834c0aee7 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt @@ -25,7 +25,7 @@ import im.vector.app.features.analytics.plan.CreatedRoom import io.element.android.features.createroom.impl.CreateRoomConfig import io.element.android.features.createroom.impl.CreateRoomDataStore import io.element.android.features.createroom.impl.userlist.UserListDataStore -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.A_MESSAGE @@ -234,9 +234,9 @@ class ConfigureRoomPresenterTests { fakeMatrixClient.givenCreateRoomResult(createRoomResult) initialState.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config)) - assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncData.Loading::class.java) + assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java) val stateAfterCreateRoom = awaitItem() - assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncData.Success::class.java) + assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Success::class.java) assertThat(stateAfterCreateRoom.createRoomAction.dataOrNull()).isEqualTo(createRoomResult.getOrNull()) } } @@ -272,16 +272,16 @@ class ConfigureRoomPresenterTests { val initialState = awaitItem() initialState.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config)) - assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncData.Loading::class.java) + assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java) val stateAfterCreateRoom = awaitItem() - assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncData.Failure::class.java) + assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java) assertThat(fakeAnalyticsService.capturedEvents.filterIsInstance()).isEmpty() fakeMatrixClient.givenUploadMediaResult(Result.success(AN_AVATAR_URL)) stateAfterCreateRoom.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config)) - assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncData.Uninitialized::class.java) - assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncData.Loading::class.java) - assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncData.Success::class.java) + assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java) + assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java) + assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Success::class.java) } } @@ -297,22 +297,22 @@ class ConfigureRoomPresenterTests { // Create initialState.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config)) - assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncData.Loading::class.java) + assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java) val stateAfterCreateRoom = awaitItem() - assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncData.Failure::class.java) - assertThat((stateAfterCreateRoom.createRoomAction as? AsyncData.Failure)?.error).isEqualTo(createRoomResult.exceptionOrNull()) + assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java) + assertThat((stateAfterCreateRoom.createRoomAction as? AsyncAction.Failure)?.error).isEqualTo(createRoomResult.exceptionOrNull()) // Retry stateAfterCreateRoom.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config)) - assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncData.Uninitialized::class.java) - assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncData.Loading::class.java) + assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java) + assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java) val stateAfterRetry = awaitItem() - assertThat(stateAfterRetry.createRoomAction).isInstanceOf(AsyncData.Failure::class.java) - assertThat((stateAfterRetry.createRoomAction as? AsyncData.Failure)?.error).isEqualTo(createRoomResult.exceptionOrNull()) + assertThat(stateAfterRetry.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java) + assertThat((stateAfterRetry.createRoomAction as? AsyncAction.Failure)?.error).isEqualTo(createRoomResult.exceptionOrNull()) // Cancel stateAfterRetry.eventSink(ConfigureRoomEvents.CancelCreateRoom) - assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncData.Uninitialized::class.java) + assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java) } } } diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt index 4446f1f3a9..63241a3a50 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt @@ -25,8 +25,7 @@ import io.element.android.features.createroom.impl.userlist.FakeUserListPresente import io.element.android.features.createroom.impl.userlist.FakeUserListPresenterFactory import io.element.android.features.createroom.impl.userlist.UserListDataStore import io.element.android.features.createroom.test.FakeStartDMAction -import io.element.android.libraries.architecture.AsyncData -import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.test.A_ROOM_ID @@ -52,20 +51,20 @@ class CreateRoomRootPresenterTests { }.test { val initialState = awaitItem() - assertThat(initialState.startDmAction).isInstanceOf(AsyncData.Uninitialized::class.java) + assertThat(initialState.startDmAction).isInstanceOf(AsyncAction.Uninitialized::class.java) assertThat(initialState.applicationName).isEqualTo(aBuildMeta().applicationName) assertThat(initialState.userListState.selectedUsers).isEmpty() assertThat(initialState.userListState.isSearchActive).isFalse() assertThat(initialState.userListState.isMultiSelectionEnabled).isFalse() val matrixUser = MatrixUser(UserId("@name:domain")) - val startDMSuccessResult = AsyncData.Success(A_ROOM_ID) - val startDMFailureResult = AsyncData.Failure(A_THROWABLE) + val startDMSuccessResult = AsyncAction.Success(A_ROOM_ID) + val startDMFailureResult = AsyncAction.Failure(A_THROWABLE) // Failure startDMAction.givenExecuteResult(startDMFailureResult) initialState.eventSink(CreateRoomRootEvents.StartDM(matrixUser)) - assertThat(awaitItem().startDmAction).isInstanceOf(AsyncData.Loading::class.java) + assertThat(awaitItem().startDmAction).isInstanceOf(AsyncAction.Loading::class.java) awaitItem().also { state -> assertThat(state.startDmAction).isEqualTo(startDMFailureResult) state.eventSink(CreateRoomRootEvents.CancelStartDM) @@ -74,10 +73,10 @@ class CreateRoomRootPresenterTests { // Success startDMAction.givenExecuteResult(startDMSuccessResult) awaitItem().also { state -> - assertThat(state.startDmAction).isEqualTo(AsyncData.Uninitialized) + assertThat(state.startDmAction).isEqualTo(AsyncAction.Uninitialized) state.eventSink(CreateRoomRootEvents.StartDM(matrixUser)) } - assertThat(awaitItem().startDmAction).isInstanceOf(AsyncData.Loading::class.java) + assertThat(awaitItem().startDmAction).isInstanceOf(AsyncAction.Loading::class.java) awaitItem().also { state -> assertThat(state.startDmAction).isEqualTo(startDMSuccessResult) } diff --git a/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/test/FakeStartDMAction.kt b/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/test/FakeStartDMAction.kt index f3e17ee79a..9e96f68fc3 100644 --- a/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/test/FakeStartDMAction.kt +++ b/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/test/FakeStartDMAction.kt @@ -18,7 +18,7 @@ package io.element.android.features.createroom.test import androidx.compose.runtime.MutableState import io.element.android.features.createroom.api.StartDMAction -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.test.A_ROOM_ID @@ -26,14 +26,14 @@ import kotlinx.coroutines.delay class FakeStartDMAction : StartDMAction { - private var executeResult: AsyncData = AsyncData.Success(A_ROOM_ID) + private var executeResult: AsyncAction = AsyncAction.Success(A_ROOM_ID) - fun givenExecuteResult(result: AsyncData) { + fun givenExecuteResult(result: AsyncAction) { executeResult = result } - override suspend fun execute(userId: UserId, actionState: MutableState>) { - actionState.value = AsyncData.Loading() + override suspend fun execute(userId: UserId, actionState: MutableState>) { + actionState.value = AsyncAction.Loading delay(1) actionState.value = executeResult } diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenter.kt index 74a5f58494..0a6d999871 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenter.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenter.kt @@ -26,7 +26,7 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import io.element.android.features.login.api.oidc.OidcAction -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.auth.OidcDetails @@ -44,33 +44,33 @@ class OidcPresenter @AssistedInject constructor( @Composable override fun present(): OidcState { - var requestState: AsyncData by remember { - mutableStateOf(AsyncData.Uninitialized) + var requestState: AsyncAction by remember { + mutableStateOf(AsyncAction.Uninitialized) } val localCoroutineScope = rememberCoroutineScope() fun handleCancel() { - requestState = AsyncData.Loading() + requestState = AsyncAction.Loading localCoroutineScope.launch { authenticationService.cancelOidcLogin() .fold( onSuccess = { // Then go back - requestState = AsyncData.Success(Unit) + requestState = AsyncAction.Success(Unit) }, onFailure = { - requestState = AsyncData.Failure(it) + requestState = AsyncAction.Failure(it) } ) } } fun handleSuccess(url: String) { - requestState = AsyncData.Loading() + requestState = AsyncAction.Loading localCoroutineScope.launch { authenticationService.loginWithOidc(url) .onFailure { - requestState = AsyncData.Failure(it) + requestState = AsyncAction.Failure(it) } // On success, the node tree will be updated, there is nothing to do } @@ -87,7 +87,7 @@ class OidcPresenter @AssistedInject constructor( when (event) { OidcEvents.Cancel -> handleCancel() is OidcEvents.OidcActionEvent -> handleAction(event.oidcAction) - OidcEvents.ClearError -> requestState = AsyncData.Uninitialized + OidcEvents.ClearError -> requestState = AsyncAction.Uninitialized } } diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcState.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcState.kt index 2571f01f0c..dc4f26d51e 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcState.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcState.kt @@ -16,11 +16,11 @@ package io.element.android.features.login.impl.oidc.webview -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.auth.OidcDetails data class OidcState( val oidcDetails: OidcDetails, - val requestState: AsyncData, + val requestState: AsyncAction, val eventSink: (OidcEvents) -> Unit ) diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcStateProvider.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcStateProvider.kt index f0b9dac200..5d44657462 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcStateProvider.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcStateProvider.kt @@ -17,20 +17,20 @@ package io.element.android.features.login.impl.oidc.webview import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.auth.OidcDetails open class OidcStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aOidcState(), - aOidcState().copy(requestState = AsyncData.Loading()), + aOidcState().copy(requestState = AsyncAction.Loading), ) } fun aOidcState() = OidcState( oidcDetails = aOidcDetails(), - requestState = AsyncData.Uninitialized, + requestState = AsyncAction.Uninitialized, eventSink = {} ) 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 66e3b31496..fb86ae18a5 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 @@ -30,7 +30,7 @@ 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.core.bool.orFalse -import io.element.android.libraries.designsystem.components.async.AsyncView +import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -76,7 +76,7 @@ fun OidcView( } ) - AsyncView( + AsyncActionView( async = state.requestState, onSuccess = { onNavigateBack() }, onErrorDismiss = { state.eventSink(OidcEvents.ClearError) } diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenterTest.kt index 2627bc384d..3920ceb597 100644 --- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenterTest.kt +++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenterTest.kt @@ -23,7 +23,7 @@ import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.features.login.api.oidc.OidcAction -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.auth.A_OIDC_DATA import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService @@ -49,7 +49,7 @@ class OidcPresenterTest { }.test { val initialState = awaitItem() assertThat(initialState.oidcDetails).isEqualTo(A_OIDC_DATA) - assertThat(initialState.requestState).isEqualTo(AsyncData.Uninitialized) + assertThat(initialState.requestState).isEqualTo(AsyncAction.Uninitialized) } } @@ -65,9 +65,9 @@ class OidcPresenterTest { val initialState = awaitItem() initialState.eventSink.invoke(OidcEvents.Cancel) val loadingState = awaitItem() - assertThat(loadingState.requestState).isEqualTo(AsyncData.Loading()) + assertThat(loadingState.requestState).isEqualTo(AsyncAction.Loading) val finalState = awaitItem() - assertThat(finalState.requestState).isEqualTo(AsyncData.Success(Unit)) + assertThat(finalState.requestState).isEqualTo(AsyncAction.Success(Unit)) } } @@ -85,9 +85,9 @@ class OidcPresenterTest { val initialState = awaitItem() initialState.eventSink.invoke(OidcEvents.Cancel) val loadingState = awaitItem() - assertThat(loadingState.requestState).isEqualTo(AsyncData.Loading()) + assertThat(loadingState.requestState).isEqualTo(AsyncAction.Loading) val finalState = awaitItem() - assertThat(finalState.requestState).isEqualTo(AsyncData.Failure(A_THROWABLE)) + assertThat(finalState.requestState).isEqualTo(AsyncAction.Failure(A_THROWABLE)) // Note: in real life I do not think this can happen, and the app should not block the user. } } @@ -104,9 +104,9 @@ class OidcPresenterTest { val initialState = awaitItem() initialState.eventSink.invoke(OidcEvents.OidcActionEvent(OidcAction.GoBack)) val loadingState = awaitItem() - assertThat(loadingState.requestState).isEqualTo(AsyncData.Loading()) + assertThat(loadingState.requestState).isEqualTo(AsyncAction.Loading) val finalState = awaitItem() - assertThat(finalState.requestState).isEqualTo(AsyncData.Success(Unit)) + assertThat(finalState.requestState).isEqualTo(AsyncAction.Success(Unit)) } } @@ -122,7 +122,7 @@ class OidcPresenterTest { val initialState = awaitItem() initialState.eventSink.invoke(OidcEvents.OidcActionEvent(OidcAction.Success("A_URL"))) val loadingState = awaitItem() - assertThat(loadingState.requestState).isEqualTo(AsyncData.Loading()) + assertThat(loadingState.requestState).isEqualTo(AsyncAction.Loading) // In this case, no success, the session is created and the node get destroyed. } } @@ -141,12 +141,12 @@ class OidcPresenterTest { val initialState = awaitItem() initialState.eventSink.invoke(OidcEvents.OidcActionEvent(OidcAction.Success("A_URL"))) val loadingState = awaitItem() - assertThat(loadingState.requestState).isEqualTo(AsyncData.Loading()) + assertThat(loadingState.requestState).isEqualTo(AsyncAction.Loading) val errorState = awaitItem() - assertThat(errorState.requestState).isEqualTo(AsyncData.Failure(A_THROWABLE)) + assertThat(errorState.requestState).isEqualTo(AsyncAction.Failure(A_THROWABLE)) errorState.eventSink.invoke(OidcEvents.ClearError) val finalState = awaitItem() - assertThat(finalState.requestState).isEqualTo(AsyncData.Uninitialized) + assertThat(finalState.requestState).isEqualTo(AsyncAction.Uninitialized) } } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenter.kt index 902c82aa0c..a7040d50e4 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenter.kt @@ -27,7 +27,7 @@ import androidx.compose.runtime.setValue import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runUpdatingState import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher @@ -60,14 +60,14 @@ class ReportMessagePresenter @AssistedInject constructor( val coroutineScope = rememberCoroutineScope() var reason by rememberSaveable { mutableStateOf("") } var blockUser by rememberSaveable { mutableStateOf(false) } - var result: MutableState> = remember { mutableStateOf(AsyncData.Uninitialized) } + var result: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } fun handleEvents(event: ReportMessageEvents) { when (event) { is ReportMessageEvents.UpdateReason -> reason = event.reason ReportMessageEvents.ToggleBlockUser -> blockUser = !blockUser ReportMessageEvents.Report -> coroutineScope.report(inputs.eventId, inputs.senderId, reason, blockUser, result) - ReportMessageEvents.ClearError -> result.value = AsyncData.Uninitialized + ReportMessageEvents.ClearError -> result.value = AsyncAction.Uninitialized } } @@ -84,7 +84,7 @@ class ReportMessagePresenter @AssistedInject constructor( userId: UserId, reason: String, blockUser: Boolean, - result: MutableState>, + result: MutableState>, ) = launch { result.runUpdatingState { val userIdToBlock = userId.takeIf { blockUser } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageState.kt index f1255c18a0..71afa43031 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageState.kt @@ -16,11 +16,11 @@ package io.element.android.features.messages.impl.report -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction data class ReportMessageState( val reason: String, val blockUser: Boolean, - val result: AsyncData, + val result: AsyncAction, val eventSink: (ReportMessageEvents) -> Unit ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageStateProvider.kt index a5847cef4a..52f0948264 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageStateProvider.kt @@ -17,7 +17,7 @@ package io.element.android.features.messages.impl.report import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction open class ReportMessageStateProvider : PreviewParameterProvider { override val values: Sequence @@ -25,9 +25,9 @@ open class ReportMessageStateProvider : PreviewParameterProvider = AsyncData.Uninitialized, + result: AsyncAction = AsyncAction.Uninitialized, ) = ReportMessageState( reason = reason, blockUser = blockUser, 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 d393619c72..a069fd615b 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 @@ -41,8 +41,9 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.features.messages.impl.R +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData -import io.element.android.libraries.designsystem.components.async.AsyncView +import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -62,8 +63,8 @@ fun ReportMessageView( modifier: Modifier = Modifier, ) { val focusManager = LocalFocusManager.current - val isSending = state.result is AsyncData.Loading - AsyncView( + val isSending = state.result is AsyncAction.Loading + AsyncActionView( async = state.result, showProgressDialog = false, onSuccess = { onBackClicked() }, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenterTests.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenterTests.kt index 9bc85a241e..3e6b6c9a67 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenterTests.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenterTests.kt @@ -20,7 +20,7 @@ import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.test.AN_EVENT_ID @@ -45,7 +45,7 @@ class ReportMessagePresenterTests { val initialState = awaitItem() assertThat(initialState.reason).isEmpty() assertThat(initialState.blockUser).isFalse() - assertThat(initialState.result).isInstanceOf(AsyncData.Uninitialized::class.java) + assertThat(initialState.result).isInstanceOf(AsyncAction.Uninitialized::class.java) } } @@ -91,8 +91,8 @@ class ReportMessagePresenterTests { initialState.eventSink(ReportMessageEvents.ToggleBlockUser) skipItems(1) initialState.eventSink(ReportMessageEvents.Report) - assertThat(awaitItem().result).isInstanceOf(AsyncData.Loading::class.java) - assertThat(awaitItem().result).isInstanceOf(AsyncData.Success::class.java) + assertThat(awaitItem().result).isInstanceOf(AsyncAction.Loading::class.java) + assertThat(awaitItem().result).isInstanceOf(AsyncAction.Success::class.java) assertThat(room.reportedContentCount).isEqualTo(1) } } @@ -106,8 +106,8 @@ class ReportMessagePresenterTests { }.test { val initialState = awaitItem() initialState.eventSink(ReportMessageEvents.Report) - assertThat(awaitItem().result).isInstanceOf(AsyncData.Loading::class.java) - assertThat(awaitItem().result).isInstanceOf(AsyncData.Success::class.java) + assertThat(awaitItem().result).isInstanceOf(AsyncAction.Loading::class.java) + assertThat(awaitItem().result).isInstanceOf(AsyncAction.Success::class.java) assertThat(room.reportedContentCount).isEqualTo(1) } } @@ -123,13 +123,13 @@ class ReportMessagePresenterTests { }.test { val initialState = awaitItem() initialState.eventSink(ReportMessageEvents.Report) - assertThat(awaitItem().result).isInstanceOf(AsyncData.Loading::class.java) + assertThat(awaitItem().result).isInstanceOf(AsyncAction.Loading::class.java) val resultState = awaitItem() - assertThat(resultState.result).isInstanceOf(AsyncData.Failure::class.java) + assertThat(resultState.result).isInstanceOf(AsyncAction.Failure::class.java) assertThat(room.reportedContentCount).isEqualTo(1) resultState.eventSink(ReportMessageEvents.ClearError) - assertThat(awaitItem().result).isInstanceOf(AsyncData.Uninitialized::class.java) + assertThat(awaitItem().result).isInstanceOf(AsyncAction.Uninitialized::class.java) } } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenter.kt index e43177b9ae..7083b9f88b 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenter.kt @@ -23,7 +23,7 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.matrix.api.MatrixClient @@ -52,7 +52,7 @@ class NotificationSettingsPresenter @Inject constructor( val systemNotificationsEnabled: MutableState = remember { mutableStateOf(systemNotificationsEnabledProvider.notificationsEnabled()) } - val changeNotificationSettingAction: MutableState> = remember { mutableStateOf(AsyncData.Uninitialized) } + val changeNotificationSettingAction: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } val localCoroutineScope = rememberCoroutineScope() val appNotificationsEnabled = userPushStore @@ -87,7 +87,7 @@ class NotificationSettingsPresenter @Inject constructor( NotificationSettingsEvents.RefreshSystemNotificationsEnabled -> { systemNotificationsEnabled.value = systemNotificationsEnabledProvider.notificationsEnabled() } - NotificationSettingsEvents.ClearNotificationChangeError -> changeNotificationSettingAction.value = AsyncData.Uninitialized + NotificationSettingsEvents.ClearNotificationChangeError -> changeNotificationSettingAction.value = AsyncAction.Uninitialized } } @@ -119,7 +119,7 @@ class NotificationSettingsPresenter @Inject constructor( val oneToOneDefaultMode = notificationSettingsService.getDefaultRoomNotificationMode(isEncrypted = false, isOneToOne = true).getOrThrow() val encryptedOneToOneDefaultMode = notificationSettingsService.getDefaultRoomNotificationMode(isEncrypted = true, isOneToOne = true).getOrThrow() - if(groupDefaultMode != encryptedGroupDefaultMode || oneToOneDefaultMode != encryptedOneToOneDefaultMode) { + if (groupDefaultMode != encryptedGroupDefaultMode || oneToOneDefaultMode != encryptedOneToOneDefaultMode) { target.value = NotificationSettingsState.MatrixSettings.Invalid(fixFailed = false) return@launch } @@ -168,19 +168,19 @@ class NotificationSettingsPresenter @Inject constructor( ) } - private fun CoroutineScope.setAtRoomNotificationsEnabled(enabled: Boolean, action: MutableState>) = launch { + private fun CoroutineScope.setAtRoomNotificationsEnabled(enabled: Boolean, action: MutableState>) = launch { suspend { notificationSettingsService.setRoomMentionEnabled(enabled).getOrThrow() }.runCatchingUpdatingState(action) } - private fun CoroutineScope.setCallNotificationsEnabled(enabled: Boolean, action: MutableState>) = launch { + private fun CoroutineScope.setCallNotificationsEnabled(enabled: Boolean, action: MutableState>) = launch { suspend { notificationSettingsService.setCallEnabled(enabled).getOrThrow() }.runCatchingUpdatingState(action) } - private fun CoroutineScope.setInviteForMeNotificationsEnabled(enabled: Boolean, action: MutableState>) = launch { + private fun CoroutineScope.setInviteForMeNotificationsEnabled(enabled: Boolean, action: MutableState>) = launch { suspend { notificationSettingsService.setInviteForMeEnabled(enabled).getOrThrow() }.runCatchingUpdatingState(action) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsState.kt index cf5f40aecc..6999acb103 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsState.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsState.kt @@ -17,18 +17,18 @@ package io.element.android.features.preferences.impl.notifications import androidx.compose.runtime.Immutable -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.room.RoomNotificationMode @Immutable data class NotificationSettingsState( val matrixSettings: MatrixSettings, val appSettings: AppSettings, - val changeNotificationSettingAction: AsyncData, + val changeNotificationSettingAction: AsyncAction, val eventSink: (NotificationSettingsEvents) -> Unit, ) { sealed interface MatrixSettings { - data object Uninitialized : MatrixSettings + data object Uninitialized : MatrixSettings data class Valid( val atRoomNotificationsEnabled: Boolean, val callNotificationsEnabled: Boolean, @@ -39,7 +39,7 @@ data class NotificationSettingsState( data class Invalid( val fixFailed: Boolean - ) : MatrixSettings + ) : MatrixSettings } data class AppSettings( diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsStateProvider.kt index a1d0e3cb0d..2dc0c02145 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsStateProvider.kt @@ -17,20 +17,20 @@ package io.element.android.features.preferences.impl.notifications import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.room.RoomNotificationMode open class NotificationSettingsStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aNotificationSettingsState(), - aNotificationSettingsState(changeNotificationSettingAction = AsyncData.Loading(Unit)), - aNotificationSettingsState(changeNotificationSettingAction = AsyncData.Failure(Throwable("error"))), + aNotificationSettingsState(changeNotificationSettingAction = AsyncAction.Loading), + aNotificationSettingsState(changeNotificationSettingAction = AsyncAction.Failure(Throwable("error"))), ) } fun aNotificationSettingsState( - changeNotificationSettingAction: AsyncData = AsyncData.Uninitialized, + changeNotificationSettingAction: AsyncAction = AsyncAction.Uninitialized, ) = NotificationSettingsState( matrixSettings = NotificationSettingsState.MatrixSettings.Valid( atRoomNotificationsEnabled = true, 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 f1066b2e9d..da8d79be50 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 @@ -27,7 +27,7 @@ import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.preferences.impl.R import io.element.android.libraries.androidutils.system.startNotificationSettingsIntent import io.element.android.libraries.designsystem.atomic.molecules.DialogLikeBannerMolecule -import io.element.android.libraries.designsystem.components.async.AsyncView +import io.element.android.libraries.designsystem.components.async.AsyncActionView 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 @@ -80,7 +80,7 @@ fun NotificationSettingsView( onInviteForMeNotificationsChanged = { state.eventSink(NotificationSettingsEvents.SetInviteForMeNotificationsEnabled(it)) }, ) } - AsyncView( + AsyncActionView( async = state.changeNotificationSettingAction, errorMessage = { stringResource(R.string.screen_notification_settings_edit_failed_updating_default_mode) }, onErrorDismiss = { state.eventSink(NotificationSettingsEvents.ClearNotificationChangeError) }, diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingPresenter.kt index 3f1edbfe28..04accef4ea 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingPresenter.kt @@ -27,7 +27,7 @@ import androidx.compose.runtime.setValue import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.matrix.api.MatrixClient @@ -55,6 +55,7 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor( interface Factory { fun create(oneToOne: Boolean): EditDefaultNotificationSettingPresenter } + @Composable override fun present(): EditDefaultNotificationSettingState { var displayMentionsOnlyDisclaimer by remember { mutableStateOf(false) } @@ -63,7 +64,7 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor( mutableStateOf(null) } - val changeNotificationSettingAction: MutableState> = remember { mutableStateOf(AsyncData.Uninitialized) } + val changeNotificationSettingAction: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } val roomsWithUserDefinedMode: MutableState> = remember { mutableStateOf(listOf()) @@ -82,7 +83,7 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor( is EditDefaultNotificationSettingStateEvents.SetNotificationMode -> { localCoroutineScope.setDefaultNotificationMode(event.mode, changeNotificationSettingAction) } - EditDefaultNotificationSettingStateEvents.ClearError -> changeNotificationSettingAction.value = AsyncData.Uninitialized + EditDefaultNotificationSettingStateEvents.ClearError -> changeNotificationSettingAction.value = AsyncAction.Uninitialized } } @@ -132,17 +133,16 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor( roomWithUserDefinedRules.contains(it.identifier()) && isOneToOne == room.isOneToOne } // locale sensitive sorting - .sortedWith(compareBy(Collator.getInstance()){ it.details.name }) + .sortedWith(compareBy(Collator.getInstance()) { it.details.name }) roomsWithUserDefinedMode.value = sortedSummaries } - private fun CoroutineScope.setDefaultNotificationMode(mode: RoomNotificationMode, action: MutableState>) = launch { + private fun CoroutineScope.setDefaultNotificationMode(mode: RoomNotificationMode, action: MutableState>) = launch { suspend { // On modern clients, we don't have different settings for encrypted and non-encrypted rooms (Legacy clients did). notificationSettingsService.setDefaultRoomNotificationMode(isEncrypted = true, mode = mode, isOneToOne = isOneToOne).getOrThrow() notificationSettingsService.setDefaultRoomNotificationMode(isEncrypted = false, mode = mode, isOneToOne = isOneToOne).getOrThrow() }.runCatchingUpdatingState(action) } - } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingState.kt index 60d881fa1c..68b29232b0 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingState.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingState.kt @@ -16,7 +16,7 @@ package io.element.android.features.preferences.impl.notifications.edit -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.roomlist.RoomSummary import kotlinx.collections.immutable.ImmutableList @@ -25,7 +25,7 @@ data class EditDefaultNotificationSettingState( val isOneToOne: Boolean, val mode: RoomNotificationMode?, val roomsWithUserDefinedMode: ImmutableList, - val changeNotificationSettingAction: AsyncData, + val changeNotificationSettingAction: AsyncAction, val displayMentionsOnlyDisclaimer: Boolean, val eventSink: (EditDefaultNotificationSettingStateEvents) -> Unit, ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingStateProvider.kt index f049a69669..0c4ef95c6c 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingStateProvider.kt @@ -17,27 +17,27 @@ package io.element.android.features.preferences.impl.notifications.edit import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails import kotlinx.collections.immutable.persistentListOf -open class EditDefaultNotificationSettingStateProvider: PreviewParameterProvider { +open class EditDefaultNotificationSettingStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( anEditDefaultNotificationSettingsState(), anEditDefaultNotificationSettingsState(isOneToOne = true), - anEditDefaultNotificationSettingsState(changeNotificationSettingAction = AsyncData.Loading(Unit)), - anEditDefaultNotificationSettingsState(changeNotificationSettingAction = AsyncData.Failure(Throwable("error"))), + anEditDefaultNotificationSettingsState(changeNotificationSettingAction = AsyncAction.Loading), + anEditDefaultNotificationSettingsState(changeNotificationSettingAction = AsyncAction.Failure(Throwable("error"))), anEditDefaultNotificationSettingsState(displayMentionsOnlyDisclaimer = true), ) } private fun anEditDefaultNotificationSettingsState( isOneToOne: Boolean = false, - changeNotificationSettingAction: AsyncData = AsyncData.Uninitialized, + changeNotificationSettingAction: AsyncAction = AsyncAction.Uninitialized, displayMentionsOnlyDisclaimer: Boolean = false, ) = EditDefaultNotificationSettingState( isOneToOne = isOneToOne, 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 7b619a7322..d03b8b2754 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 @@ -23,7 +23,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import io.element.android.features.preferences.impl.R -import io.element.android.libraries.designsystem.components.async.AsyncView +import io.element.android.libraries.designsystem.components.async.AsyncActionView 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 @@ -117,7 +117,7 @@ fun EditDefaultNotificationSettingView( } } } - AsyncView( + AsyncActionView( async = state.changeNotificationSettingAction, errorMessage = { stringResource(R.string.screen_notification_settings_edit_failed_updating_default_mode) }, onErrorDismiss = { state.eventSink(EditDefaultNotificationSettingStateEvents.ClearError) }, diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt index 60498d7141..2a51aad22b 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt @@ -31,7 +31,7 @@ import androidx.core.net.toUri import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.core.mimetype.MimeTypes @@ -92,7 +92,7 @@ class EditUserProfilePresenter @AssistedInject constructor( } } - val saveAction: MutableState> = remember { mutableStateOf(AsyncData.Uninitialized) } + val saveAction: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } val localCoroutineScope = rememberCoroutineScope() fun handleEvents(event: EditUserProfileEvents) { when (event) { @@ -111,7 +111,7 @@ class EditUserProfilePresenter @AssistedInject constructor( } is EditUserProfileEvents.UpdateDisplayName -> userDisplayName = event.name - EditUserProfileEvents.CancelSaveChanges -> saveAction.value = AsyncData.Uninitialized + EditUserProfileEvents.CancelSaveChanges -> saveAction.value = AsyncAction.Uninitialized } } @@ -126,7 +126,7 @@ class EditUserProfilePresenter @AssistedInject constructor( displayName = userDisplayName.orEmpty(), userAvatarUrl = userAvatarUri, avatarActions = avatarActions, - saveButtonEnabled = canSave && saveAction.value !is AsyncData.Loading, + saveButtonEnabled = canSave && saveAction.value !is AsyncAction.Loading, saveAction = saveAction.value, cameraPermissionState = cameraPermissionState, eventSink = { handleEvents(it) }, @@ -140,7 +140,12 @@ class EditUserProfilePresenter @AssistedInject constructor( // Need to call `toUri()?.toString()` to make the test pass (we mockk Uri) avatarUri?.toString()?.trim() != currentUser.avatarUrl?.toUri()?.toString()?.trim() - private fun CoroutineScope.saveChanges(name: String?, avatarUri: Uri?, currentUser: MatrixUser, action: MutableState>) = launch { + private fun CoroutineScope.saveChanges( + name: String?, + avatarUri: Uri?, + currentUser: MatrixUser, + action: MutableState>, + ) = launch { val results = mutableListOf>() suspend { if (!name.isNullOrEmpty() && name.trim() != currentUser.displayName.orEmpty().trim()) { diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileState.kt index 600c16858b..c37dba8c3a 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileState.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileState.kt @@ -17,7 +17,7 @@ package io.element.android.features.preferences.impl.user.editprofile import android.net.Uri -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.ui.media.AvatarAction import io.element.android.libraries.permissions.api.PermissionsState @@ -29,7 +29,7 @@ data class EditUserProfileState( val userAvatarUrl: Uri?, val avatarActions: ImmutableList, val saveButtonEnabled: Boolean, - val saveAction: AsyncData, + val saveAction: AsyncAction, val cameraPermissionState: PermissionsState, val eventSink: (EditUserProfileEvents) -> Unit ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt index f970e2c60d..9d0d027433 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt @@ -17,7 +17,7 @@ package io.element.android.features.preferences.impl.user.editprofile import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.permissions.api.aPermissionsState import kotlinx.collections.immutable.persistentListOf @@ -35,7 +35,7 @@ fun aEditUserProfileState() = EditUserProfileState( displayName = "John Doe", userAvatarUrl = null, avatarActions = persistentListOf(), - saveAction = AsyncData.Uninitialized, + saveAction = AsyncAction.Uninitialized, saveButtonEnabled = true, cameraPermissionState = aPermissionsState(showDialog = false), eventSink = {} 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 66aaeb6c40..8f0add74ce 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 @@ -43,7 +43,7 @@ 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.designsystem.components.LabelledOutlinedTextField -import io.element.android.libraries.designsystem.components.async.AsyncView +import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.preview.ElementPreview @@ -147,7 +147,7 @@ fun EditUserProfileView( onActionSelected = { state.eventSink(EditUserProfileEvents.HandleAvatarAction(it)) } ) - AsyncView( + AsyncActionView( async = state.saveAction, progressText = stringResource(R.string.screen_edit_profile_updating_details), onSuccess = { onProfileEdited() }, diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt index 37e95378ba..8b3bb0c2f8 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt @@ -21,7 +21,7 @@ import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.test.AN_AVATAR_URL @@ -110,7 +110,7 @@ class EditUserProfilePresenterTest { AvatarAction.Remove ) assertThat(initialState.saveButtonEnabled).isFalse() - assertThat(initialState.saveAction).isInstanceOf(AsyncData.Uninitialized::class.java) + assertThat(initialState.saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java) } } @@ -359,7 +359,7 @@ class EditUserProfilePresenterTest { initialState.eventSink(EditUserProfileEvents.Save) skipItems(2) assertThat(matrixClient.uploadAvatarCalled).isFalse() - assertThat(awaitItem().saveAction).isInstanceOf(AsyncData.Failure::class.java) + assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) } } @@ -406,9 +406,9 @@ class EditUserProfilePresenterTest { initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("foo")) initialState.eventSink(EditUserProfileEvents.Save) skipItems(2) - assertThat(awaitItem().saveAction).isInstanceOf(AsyncData.Failure::class.java) + assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) initialState.eventSink(EditUserProfileEvents.CancelSaveChanges) - assertThat(awaitItem().saveAction).isInstanceOf(AsyncData.Uninitialized::class.java) + assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java) } } @@ -421,8 +421,8 @@ class EditUserProfilePresenterTest { initialState.eventSink(event) initialState.eventSink(EditUserProfileEvents.Save) skipItems(1) - assertThat(awaitItem().saveAction).isInstanceOf(AsyncData.Loading::class.java) - assertThat(awaitItem().saveAction).isInstanceOf(AsyncData.Failure::class.java) + assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Loading::class.java) + assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) } } diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenter.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenter.kt index eac789af3e..34506b8e8d 100644 --- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenter.kt +++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenter.kt @@ -30,7 +30,7 @@ import io.element.android.features.rageshake.api.reporter.BugReporter import io.element.android.features.rageshake.api.reporter.BugReporterListener import io.element.android.features.rageshake.api.screenshot.ScreenshotHolder import io.element.android.features.rageshake.impl.logs.VectorFileLogger -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @@ -45,27 +45,27 @@ class BugReportPresenter @Inject constructor( private class BugReporterUploadListener( private val sendingProgress: MutableFloatState, - private val sendingAction: MutableState> + private val sendingAction: MutableState> ) : BugReporterListener { override fun onUploadCancelled() { sendingProgress.floatValue = 0f - sendingAction.value = AsyncData.Uninitialized + sendingAction.value = AsyncAction.Uninitialized } override fun onUploadFailed(reason: String?) { sendingProgress.floatValue = 0f - sendingAction.value = AsyncData.Failure(Exception(reason)) + sendingAction.value = AsyncAction.Failure(Exception(reason)) } override fun onProgress(progress: Int) { sendingProgress.floatValue = progress.toFloat() / 100 - sendingAction.value = AsyncData.Loading() + sendingAction.value = AsyncAction.Loading } override fun onUploadSucceed() { sendingProgress.floatValue = 0f - sendingAction.value = AsyncData.Success(Unit) + sendingAction.value = AsyncAction.Success(Unit) } } @@ -83,8 +83,8 @@ class BugReportPresenter @Inject constructor( val sendingProgress = remember { mutableFloatStateOf(0f) } - val sendingAction: MutableState> = remember { - mutableStateOf(AsyncData.Uninitialized) + val sendingAction: MutableState> = remember { + mutableStateOf(AsyncAction.Uninitialized) } val formState: MutableState = remember { mutableStateOf(BugReportFormState.Default) @@ -109,7 +109,7 @@ class BugReportPresenter @Inject constructor( } BugReportEvents.ClearError -> { sendingProgress.floatValue = 0f - sendingAction.value = AsyncData.Uninitialized + sendingAction.value = AsyncAction.Uninitialized } } } diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportState.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportState.kt index 1401369cc2..c3bfbec888 100644 --- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportState.kt +++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportState.kt @@ -17,7 +17,7 @@ package io.element.android.features.rageshake.impl.bugreport import android.os.Parcelable -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import kotlinx.parcelize.Parcelize data class BugReportState( @@ -25,11 +25,11 @@ data class BugReportState( val hasCrashLogs: Boolean, val screenshotUri: String?, val sendingProgress: Float, - val sending: AsyncData, + val sending: AsyncAction, val eventSink: (BugReportEvents) -> Unit ) { val submitEnabled = - formState.description.length > 10 && sending !is AsyncData.Loading + formState.description.length > 10 && sending !is AsyncAction.Loading } @Parcelize diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportStateProvider.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportStateProvider.kt index e670562637..bb0d273de4 100644 --- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportStateProvider.kt +++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportStateProvider.kt @@ -17,7 +17,7 @@ package io.element.android.features.rageshake.impl.bugreport import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction open class BugReportStateProvider : PreviewParameterProvider { override val values: Sequence @@ -31,8 +31,8 @@ open class BugReportStateProvider : PreviewParameterProvider { hasCrashLogs = true, screenshotUri = "aUri" ), - aBugReportState().copy(sending = AsyncData.Loading()), - aBugReportState().copy(sending = AsyncData.Success(Unit)), + aBugReportState().copy(sending = AsyncAction.Loading), + aBugReportState().copy(sending = AsyncAction.Success(Unit)), ) } @@ -41,6 +41,6 @@ fun aBugReportState() = BugReportState( hasCrashLogs = false, screenshotUri = null, sendingProgress = 0F, - sending = AsyncData.Uninitialized, + sending = AsyncAction.Uninitialized, eventSink = {} ) 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 2d1b7fdd6e..34eaf3316a 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 @@ -37,8 +37,8 @@ import androidx.compose.ui.unit.dp import coil.compose.AsyncImage import coil.request.ImageRequest import io.element.android.features.rageshake.impl.R -import io.element.android.libraries.architecture.AsyncData -import io.element.android.libraries.designsystem.components.async.AsyncView +import io.element.android.libraries.architecture.AsyncAction +import io.element.android.libraries.designsystem.components.async.AsyncActionView 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 @@ -67,7 +67,7 @@ fun BugReportView( title = stringResource(id = CommonStrings.common_report_a_problem), onBackPressed = onBackPressed ) { - val isFormEnabled = state.sending !is AsyncData.Loading + val isFormEnabled = state.sending !is AsyncAction.Loading var descriptionFieldState by textFieldState( stateValue = state.formState.description ) @@ -150,7 +150,7 @@ fun BugReportView( } } - AsyncView( + AsyncActionView( async = state.sending, showProgressDialog = false, onSuccess = { diff --git a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt index 3c2607a08a..9161862256 100644 --- a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt +++ b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt @@ -24,7 +24,7 @@ import io.element.android.features.rageshake.test.crash.A_CRASH_DATA import io.element.android.features.rageshake.test.crash.FakeCrashDataStore import io.element.android.features.rageshake.test.screenshot.A_SCREENSHOT_URI import io.element.android.features.rageshake.test.screenshot.FakeScreenshotHolder -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.test.A_FAILURE_REASON import io.element.android.tests.testutils.WarmUpRule import kotlinx.coroutines.test.runTest @@ -53,7 +53,7 @@ class BugReportPresenterTest { val initialState = awaitItem() assertThat(initialState.hasCrashLogs).isFalse() assertThat(initialState.formState).isEqualTo(BugReportFormState.Default) - assertThat(initialState.sending).isEqualTo(AsyncData.Uninitialized) + assertThat(initialState.sending).isEqualTo(AsyncAction.Uninitialized) assertThat(initialState.screenshotUri).isNull() assertThat(initialState.sendingProgress).isEqualTo(0f) assertThat(initialState.submitEnabled).isFalse() @@ -174,13 +174,13 @@ class BugReportPresenterTest { initialState.eventSink.invoke(BugReportEvents.SendBugReport) skipItems(1) val progressState = awaitItem() - assertThat(progressState.sending).isEqualTo(AsyncData.Loading(null)) + assertThat(progressState.sending).isEqualTo(AsyncAction.Loading) assertThat(progressState.sendingProgress).isEqualTo(0f) assertThat(progressState.submitEnabled).isFalse() assertThat(awaitItem().sendingProgress).isEqualTo(0.5f) assertThat(awaitItem().sendingProgress).isEqualTo(1f) skipItems(1) - assertThat(awaitItem().sending).isEqualTo(AsyncData.Success(Unit)) + assertThat(awaitItem().sending).isEqualTo(AsyncAction.Success(Unit)) } } @@ -199,17 +199,17 @@ class BugReportPresenterTest { initialState.eventSink.invoke(BugReportEvents.SendBugReport) skipItems(1) val progressState = awaitItem() - assertThat(progressState.sending).isEqualTo(AsyncData.Loading(null)) + assertThat(progressState.sending).isEqualTo(AsyncAction.Loading) assertThat(progressState.sendingProgress).isEqualTo(0f) assertThat(awaitItem().sendingProgress).isEqualTo(0.5f) // Failure assertThat(awaitItem().sendingProgress).isEqualTo(0f) - assertThat((awaitItem().sending as AsyncData.Failure).error.message).isEqualTo(A_FAILURE_REASON) + assertThat((awaitItem().sending as AsyncAction.Failure).error.message).isEqualTo(A_FAILURE_REASON) // Reset failure initialState.eventSink.invoke(BugReportEvents.ClearError) val lastItem = awaitItem() assertThat(lastItem.sendingProgress).isEqualTo(0f) - assertThat(lastItem.sending).isInstanceOf(AsyncData.Uninitialized::class.java) + assertThat(lastItem.sending).isInstanceOf(AsyncAction.Uninitialized::class.java) } } @@ -228,12 +228,12 @@ class BugReportPresenterTest { initialState.eventSink.invoke(BugReportEvents.SendBugReport) skipItems(1) val progressState = awaitItem() - assertThat(progressState.sending).isEqualTo(AsyncData.Loading(null)) + assertThat(progressState.sending).isEqualTo(AsyncAction.Loading) assertThat(progressState.sendingProgress).isEqualTo(0f) assertThat(awaitItem().sendingProgress).isEqualTo(0.5f) // Cancelled assertThat(awaitItem().sendingProgress).isEqualTo(0f) - assertThat(awaitItem().sending).isEqualTo(AsyncData.Uninitialized) + assertThat(awaitItem().sending).isEqualTo(AsyncAction.Uninitialized) } } } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenter.kt index f48ec727e1..6682db392f 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenter.kt @@ -29,7 +29,7 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.core.net.toUri -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.core.mimetype.MimeTypes @@ -116,7 +116,7 @@ class RoomDetailsEditPresenter @Inject constructor( } } - val saveAction: MutableState> = remember { mutableStateOf(AsyncData.Uninitialized) } + val saveAction: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } val localCoroutineScope = rememberCoroutineScope() fun handleEvents(event: RoomDetailsEditEvents) { when (event) { @@ -136,7 +136,7 @@ class RoomDetailsEditPresenter @Inject constructor( is RoomDetailsEditEvents.UpdateRoomName -> roomName = event.name is RoomDetailsEditEvents.UpdateRoomTopic -> roomTopic = event.topic.takeUnless { it.isEmpty() } - RoomDetailsEditEvents.CancelSaveChanges -> saveAction.value = AsyncData.Uninitialized + RoomDetailsEditEvents.CancelSaveChanges -> saveAction.value = AsyncAction.Uninitialized } } @@ -156,7 +156,12 @@ class RoomDetailsEditPresenter @Inject constructor( ) } - private fun CoroutineScope.saveChanges(name: String, topic: String?, avatarUri: Uri?, action: MutableState>) = launch { + private fun CoroutineScope.saveChanges( + name: String, + topic: String?, + avatarUri: Uri?, + action: MutableState>, + ) = launch { val results = mutableListOf>() suspend { if (topic.orEmpty().trim() != room.topic.orEmpty().trim()) { diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditState.kt index c7076bd67f..d85450b59f 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditState.kt @@ -17,7 +17,7 @@ package io.element.android.features.roomdetails.impl.edit import android.net.Uri -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.ui.media.AvatarAction import io.element.android.libraries.permissions.api.PermissionsState import kotlinx.collections.immutable.ImmutableList @@ -32,7 +32,7 @@ data class RoomDetailsEditState( val canChangeAvatar: Boolean, val avatarActions: ImmutableList, val saveButtonEnabled: Boolean, - val saveAction: AsyncData, + val saveAction: AsyncAction, val cameraPermissionState: PermissionsState, val eventSink: (RoomDetailsEditEvents) -> Unit ) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditStateProvider.kt index 9d62760542..d70c83b9a0 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditStateProvider.kt @@ -18,7 +18,7 @@ package io.element.android.features.roomdetails.impl.edit import android.net.Uri import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.permissions.api.aPermissionsState import kotlinx.collections.immutable.persistentListOf @@ -30,8 +30,8 @@ open class RoomDetailsEditStateProvider : PreviewParameterProvider(null) } val roomMember by room.getRoomMemberAsState(roomMemberId) - val startDmActionState: MutableState> = remember { mutableStateOf(AsyncData.Uninitialized) } + val startDmActionState: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } // the room member is not really live... val isBlocked: MutableState> = remember(roomMember) { val isIgnored = roomMember?.isIgnored @@ -98,7 +99,7 @@ class RoomMemberDetailsPresenter @AssistedInject constructor( } } RoomMemberDetailsEvents.ClearStartDMState -> { - startDmActionState.value = AsyncData.Uninitialized + startDmActionState.value = AsyncAction.Uninitialized } } } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsState.kt index db7b926db9..817e5da46b 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsState.kt @@ -16,6 +16,7 @@ package io.element.android.features.roomdetails.impl.members.details +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.core.RoomId @@ -24,7 +25,7 @@ data class RoomMemberDetailsState( val userName: String?, val avatarUrl: String?, val isBlocked: AsyncData, - val startDmActionState: AsyncData, + val startDmActionState: AsyncAction, val displayConfirmationDialog: ConfirmationDialog?, val isCurrentUser: Boolean, val eventSink: (RoomMemberDetailsEvents) -> Unit diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsStateProvider.kt index b060d2de7c..ff4b9ee1b3 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsStateProvider.kt @@ -17,6 +17,7 @@ package io.element.android.features.roomdetails.impl.members.details import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData open class RoomMemberDetailsStateProvider : PreviewParameterProvider { @@ -28,7 +29,7 @@ open class RoomMemberDetailsStateProvider : PreviewParameterProvider> = remember { mutableStateOf(AsyncData.Uninitialized) } - val restoreDefaultAction: MutableState> = remember { mutableStateOf(AsyncData.Uninitialized) } + val setNotificationSettingAction: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } + val restoreDefaultAction: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } val roomNotificationSettings: MutableState> = remember { mutableStateOf(AsyncData.Uninitialized) @@ -103,7 +104,7 @@ class RoomNotificationSettingsPresenter @AssistedInject constructor( localCoroutineScope.restoreDefaultRoomNotificationMode(restoreDefaultAction, pendingSetDefault) } else { defaultRoomNotificationMode.value?.let { - localCoroutineScope.setRoomNotificationMode(it, pendingRoomNotificationMode, pendingSetDefault, setNotificationSettingAction) + localCoroutineScope.setRoomNotificationMode(it, pendingRoomNotificationMode, pendingSetDefault, setNotificationSettingAction) } } } @@ -111,10 +112,10 @@ class RoomNotificationSettingsPresenter @AssistedInject constructor( localCoroutineScope.restoreDefaultRoomNotificationMode(restoreDefaultAction, pendingSetDefault) } RoomNotificationSettingsEvents.ClearSetNotificationError -> { - setNotificationSettingAction.value = AsyncData.Uninitialized + setNotificationSettingAction.value = AsyncAction.Uninitialized } RoomNotificationSettingsEvents.ClearRestoreDefaultError -> { - restoreDefaultAction.value = AsyncData.Uninitialized + restoreDefaultAction.value = AsyncAction.Uninitialized } } } @@ -169,7 +170,7 @@ class RoomNotificationSettingsPresenter @AssistedInject constructor( mode: RoomNotificationMode, pendingModeState: MutableState, pendingDefaultState: MutableState, - action: MutableState> + action: MutableState> ) = launch { suspend { pendingModeState.value = mode @@ -184,7 +185,7 @@ class RoomNotificationSettingsPresenter @AssistedInject constructor( } private fun CoroutineScope.restoreDefaultRoomNotificationMode( - action: MutableState>, + action: MutableState>, pendingDefaultState: MutableState ) = launch { suspend { diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsState.kt index a009e5b4e5..6f0ec6ea77 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsState.kt @@ -16,6 +16,7 @@ package io.element.android.features.roomdetails.impl.notificationsettings +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationSettings @@ -27,8 +28,8 @@ data class RoomNotificationSettingsState( val pendingRoomNotificationMode: RoomNotificationMode?, val pendingSetDefault: Boolean?, val defaultRoomNotificationMode: RoomNotificationMode?, - val setNotificationSettingAction: AsyncData, - val restoreDefaultAction: AsyncData, + val setNotificationSettingAction: AsyncAction, + val restoreDefaultAction: AsyncAction, val displayMentionsOnlyDisclaimer: Boolean, val eventSink: (RoomNotificationSettingsEvents) -> Unit ) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsStateProvider.kt index 5b4fac7b0d..04f0c0859b 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsStateProvider.kt @@ -17,6 +17,7 @@ package io.element.android.features.roomdetails.impl.notificationsettings import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationSettings @@ -26,17 +27,17 @@ internal class RoomNotificationSettingsStateProvider : PreviewParameterProvider< get() = sequenceOf( aRoomNotificationSettingsState(), aRoomNotificationSettingsState(isDefault = false), - aRoomNotificationSettingsState(setNotificationSettingAction = AsyncData.Loading(Unit)), - aRoomNotificationSettingsState(setNotificationSettingAction = AsyncData.Failure(Throwable("error"))), - aRoomNotificationSettingsState(restoreDefaultAction = AsyncData.Loading(Unit)), - aRoomNotificationSettingsState(restoreDefaultAction = AsyncData.Failure(Throwable("error"))), + aRoomNotificationSettingsState(setNotificationSettingAction = AsyncAction.Loading), + aRoomNotificationSettingsState(setNotificationSettingAction = AsyncAction.Failure(Throwable("error"))), + aRoomNotificationSettingsState(restoreDefaultAction = AsyncAction.Loading), + aRoomNotificationSettingsState(restoreDefaultAction = AsyncAction.Failure(Throwable("error"))), aRoomNotificationSettingsState(displayMentionsOnlyDisclaimer = true) ) private fun aRoomNotificationSettingsState( isDefault: Boolean = true, - setNotificationSettingAction: AsyncData = AsyncData.Uninitialized, - restoreDefaultAction: AsyncData = AsyncData.Uninitialized, + setNotificationSettingAction: AsyncAction = AsyncAction.Uninitialized, + restoreDefaultAction: AsyncAction = AsyncAction.Uninitialized, displayMentionsOnlyDisclaimer: Boolean = false, ): RoomNotificationSettingsState { return RoomNotificationSettingsState( 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 6bba2436b3..b70c21798c 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 @@ -33,7 +33,7 @@ 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.core.bool.orTrue -import io.element.android.libraries.designsystem.components.async.AsyncView +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.preferences.PreferenceCategory import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch @@ -157,14 +157,14 @@ private fun RoomSpecificNotificationSettingsView( } } - AsyncView( + AsyncActionView( async = state.setNotificationSettingAction, onSuccess = {}, errorMessage = { stringResource(R.string.screen_notification_settings_edit_failed_updating_default_mode) }, onErrorDismiss = { state.eventSink(RoomNotificationSettingsEvents.ClearSetNotificationError) }, ) - AsyncView( + AsyncActionView( async = state.restoreDefaultAction, onSuccess = {}, errorMessage = { stringResource(R.string.screen_notification_settings_edit_failed_updating_default_mode) }, diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsStateProvider.kt index 26f201d949..8e0bea68a6 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsStateProvider.kt @@ -17,6 +17,7 @@ package io.element.android.features.roomdetails.impl.notificationsettings import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationSettings @@ -35,8 +36,8 @@ internal class UserDefinedRoomNotificationSettingsStateProvider : PreviewParamet pendingRoomNotificationMode = null, pendingSetDefault = null, defaultRoomNotificationMode = RoomNotificationMode.ALL_MESSAGES, - setNotificationSettingAction = AsyncData.Uninitialized, - restoreDefaultAction = AsyncData.Uninitialized, + setNotificationSettingAction = AsyncAction.Uninitialized, + restoreDefaultAction = AsyncAction.Uninitialized, displayMentionsOnlyDisclaimer = false, eventSink = { }, ), 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 9b982542fd..df1a41ea87 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 @@ -29,7 +29,7 @@ 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.core.bool.orTrue -import io.element.android.libraries.designsystem.components.async.AsyncView +import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -81,14 +81,14 @@ fun UserDefinedRoomNotificationSettingsView( } ) - AsyncView( + AsyncActionView( async = state.setNotificationSettingAction, onSuccess = {}, errorMessage = { stringResource(R.string.screen_notification_settings_edit_failed_updating_default_mode) }, onErrorDismiss = { state.eventSink(RoomNotificationSettingsEvents.ClearSetNotificationError) }, ) - AsyncView( + AsyncActionView( async = state.restoreDefaultAction, onSuccess = { onBackPressed() }, errorMessage = { stringResource(R.string.screen_notification_settings_edit_failed_updating_default_mode) }, diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/edit/RoomDetailsEditPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/edit/RoomDetailsEditPresenterTest.kt index d6a325b51d..a9a2d81b20 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/edit/RoomDetailsEditPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/edit/RoomDetailsEditPresenterTest.kt @@ -24,7 +24,7 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.roomdetails.aMatrixRoom import io.element.android.features.roomdetails.impl.edit.RoomDetailsEditEvents import io.element.android.features.roomdetails.impl.edit.RoomDetailsEditPresenter -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.test.AN_AVATAR_URL @@ -108,7 +108,7 @@ class RoomDetailsEditPresenterTest { AvatarAction.Remove ) assertThat(initialState.saveButtonEnabled).isFalse() - assertThat(initialState.saveAction).isInstanceOf(AsyncData.Uninitialized::class.java) + assertThat(initialState.saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java) } } @@ -533,7 +533,7 @@ class RoomDetailsEditPresenterTest { assertThat(room.newAvatarData).isNull() assertThat(room.removedAvatar).isFalse() - assertThat(awaitItem().saveAction).isInstanceOf(AsyncData.Failure::class.java) + assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) } } @@ -594,10 +594,10 @@ class RoomDetailsEditPresenterTest { initialState.eventSink(RoomDetailsEditEvents.Save) skipItems(2) - assertThat(awaitItem().saveAction).isInstanceOf(AsyncData.Failure::class.java) + assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) initialState.eventSink(RoomDetailsEditEvents.CancelSaveChanges) - assertThat(awaitItem().saveAction).isInstanceOf(AsyncData.Uninitialized::class.java) + assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java) } } @@ -613,8 +613,8 @@ class RoomDetailsEditPresenterTest { initialState.eventSink(RoomDetailsEditEvents.Save) skipItems(1) - assertThat(awaitItem().saveAction).isInstanceOf(AsyncData.Loading::class.java) - assertThat(awaitItem().saveAction).isInstanceOf(AsyncData.Failure::class.java) + assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Loading::class.java) + assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) } } diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/details/RoomMemberDetailsPresenterTests.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/details/RoomMemberDetailsPresenterTests.kt index f386c0e887..f1553f8d06 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/details/RoomMemberDetailsPresenterTests.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/details/RoomMemberDetailsPresenterTests.kt @@ -27,9 +27,9 @@ import io.element.android.features.roomdetails.impl.members.aRoomMember import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsEvents import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsPresenter import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsState +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.MatrixClient -import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.RoomMember @@ -204,14 +204,14 @@ class RoomMemberDetailsPresenterTests { presenter.present() }.test { val initialState = awaitItem() - assertThat(initialState.startDmActionState).isInstanceOf(AsyncData.Uninitialized::class.java) - val startDMSuccessResult = AsyncData.Success(A_ROOM_ID) - val startDMFailureResult = AsyncData.Failure(A_THROWABLE) + assertThat(initialState.startDmActionState).isInstanceOf(AsyncAction.Uninitialized::class.java) + val startDMSuccessResult = AsyncAction.Success(A_ROOM_ID) + val startDMFailureResult = AsyncAction.Failure(A_THROWABLE) // Failure startDMAction.givenExecuteResult(startDMFailureResult) initialState.eventSink(RoomMemberDetailsEvents.StartDM) - assertThat(awaitItem().startDmActionState).isInstanceOf(AsyncData.Loading::class.java) + assertThat(awaitItem().startDmActionState).isInstanceOf(AsyncAction.Loading::class.java) awaitItem().also { state -> assertThat(state.startDmActionState).isEqualTo(startDMFailureResult) state.eventSink(RoomMemberDetailsEvents.ClearStartDMState) @@ -220,10 +220,10 @@ class RoomMemberDetailsPresenterTests { // Success startDMAction.givenExecuteResult(startDMSuccessResult) awaitItem().also { state -> - assertThat(state.startDmActionState).isEqualTo(AsyncData.Uninitialized) + assertThat(state.startDmActionState).isEqualTo(AsyncAction.Uninitialized) state.eventSink(RoomMemberDetailsEvents.StartDM) } - assertThat(awaitItem().startDmActionState).isInstanceOf(AsyncData.Loading::class.java) + assertThat(awaitItem().startDmActionState).isInstanceOf(AsyncAction.Loading::class.java) awaitItem().also { state -> assertThat(state.startDmActionState).isEqualTo(startDMSuccessResult) } diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenter.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenter.kt index bb9cfb8a0a..7f19039979 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenter.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenter.kt @@ -25,7 +25,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import io.element.android.features.securebackup.impl.loggerTagDisable -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.core.meta.BuildMeta @@ -44,7 +44,7 @@ class SecureBackupDisablePresenter @Inject constructor( override fun present(): SecureBackupDisableState { val backupState by encryptionService.backupStateStateFlow.collectAsState() Timber.tag(loggerTagDisable.value).d("backupState: $backupState") - val disableAction = remember { mutableStateOf>(AsyncData.Uninitialized) } + val disableAction: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } val coroutineScope = rememberCoroutineScope() var showDialog by remember { mutableStateOf(false) } fun handleEvents(event: SecureBackupDisableEvents) { @@ -57,7 +57,7 @@ class SecureBackupDisablePresenter @Inject constructor( } SecureBackupDisableEvents.DismissDialogs -> { showDialog = false - disableAction.value = AsyncData.Uninitialized + disableAction.value = AsyncAction.Uninitialized } } } @@ -71,7 +71,7 @@ class SecureBackupDisablePresenter @Inject constructor( ) } - private fun CoroutineScope.disableBackup(disableAction: MutableState>) = launch { + private fun CoroutineScope.disableBackup(disableAction: MutableState>) = launch { suspend { Timber.tag(loggerTagDisable.value).d("Calling encryptionService.disableRecovery()") encryptionService.disableRecovery().getOrThrow() diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableState.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableState.kt index 3698752749..2573812f75 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableState.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableState.kt @@ -16,12 +16,12 @@ package io.element.android.features.securebackup.impl.disable -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.encryption.BackupState data class SecureBackupDisableState( val backupState: BackupState, - val disableAction: AsyncData, + val disableAction: AsyncAction, val showConfirmationDialog: Boolean, val appName: String, val eventSink: (SecureBackupDisableEvents) -> Unit diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableStateProvider.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableStateProvider.kt index 44bee84d2d..8d23d1178b 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableStateProvider.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableStateProvider.kt @@ -17,7 +17,7 @@ package io.element.android.features.securebackup.impl.disable import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.encryption.BackupState open class SecureBackupDisableStateProvider : PreviewParameterProvider { @@ -25,15 +25,15 @@ open class SecureBackupDisableStateProvider : PreviewParameterProvider = AsyncData.Uninitialized, + disableAction: AsyncAction = AsyncAction.Uninitialized, showConfirmationDialog: Boolean = false, ) = SecureBackupDisableState( backupState = backupState, diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableView.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableView.kt index 6d972223a8..7c00582a0b 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableView.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableView.kt @@ -34,6 +34,7 @@ import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.securebackup.impl.R +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog @@ -53,7 +54,7 @@ fun SecureBackupDisableView( modifier: Modifier = Modifier, ) { LaunchedEffect(state.disableAction) { - if (state.disableAction is AsyncData.Success) { + if (state.disableAction is AsyncAction.Success) { onDone() } } @@ -72,7 +73,7 @@ fun SecureBackupDisableView( onConfirm = { state.eventSink.invoke(SecureBackupDisableEvents.DisableBackup(force = true)) }, onDismiss = { state.eventSink.invoke(SecureBackupDisableEvents.DismissDialogs) }, ) - } else if (state.disableAction is AsyncData.Failure) { + } else if (state.disableAction is AsyncAction.Failure) { ErrorDialog( content = state.disableAction.error.let { it.message ?: it.toString() }, onDismiss = { state.eventSink.invoke(SecureBackupDisableEvents.DismissDialogs) }, diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenter.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenter.kt index f79176b3a9..2940ef576e 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenter.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenter.kt @@ -27,7 +27,7 @@ import androidx.compose.runtime.setValue import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyUserStory import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState import io.element.android.features.securebackup.impl.tools.RecoveryKeyTools -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.matrix.api.encryption.EncryptionService @@ -46,14 +46,14 @@ class SecureBackupEnterRecoveryKeyPresenter @Inject constructor( var recoveryKey by rememberSaveable { mutableStateOf("") } - val submitAction = remember { - mutableStateOf>(AsyncData.Uninitialized) + val submitAction: MutableState> = remember { + mutableStateOf(AsyncAction.Uninitialized) } fun handleEvents(event: SecureBackupEnterRecoveryKeyEvents) { when (event) { SecureBackupEnterRecoveryKeyEvents.ClearDialog -> { - submitAction.value = AsyncData.Uninitialized + submitAction.value = AsyncAction.Uninitialized } is SecureBackupEnterRecoveryKeyEvents.OnRecoveryKeyChange -> { val previousRecoveryKey = recoveryKey @@ -86,7 +86,7 @@ class SecureBackupEnterRecoveryKeyPresenter @Inject constructor( private fun CoroutineScope.submitRecoveryKey( recoveryKey: String, - action: MutableState> + action: MutableState> ) = launch { suspend { encryptionService.recover(recoveryKey).getOrThrow() diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyState.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyState.kt index 9f00714f38..c064a3fc13 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyState.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyState.kt @@ -17,12 +17,12 @@ package io.element.android.features.securebackup.impl.enter import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction // Do not use default value, so no member get forgotten in the presenters. data class SecureBackupEnterRecoveryKeyState( val recoveryKeyViewState: RecoveryKeyViewState, val isSubmitEnabled: Boolean, - val submitAction: AsyncData, + val submitAction: AsyncAction, val eventSink: (SecureBackupEnterRecoveryKeyEvents) -> Unit ) diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyStateProvider.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyStateProvider.kt index 6350eeb696..cb8d1cba03 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyStateProvider.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyStateProvider.kt @@ -20,6 +20,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyUserStory import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState import io.element.android.features.securebackup.impl.setup.views.aFormattedRecoveryKey +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData open class SecureBackupEnterRecoveryKeyStateProvider : PreviewParameterProvider { @@ -27,15 +28,15 @@ open class SecureBackupEnterRecoveryKeyStateProvider : PreviewParameterProvider< get() = sequenceOf( aSecureBackupEnterRecoveryKeyState(recoveryKey = ""), aSecureBackupEnterRecoveryKeyState(), - aSecureBackupEnterRecoveryKeyState(submitAction = AsyncData.Loading()), - aSecureBackupEnterRecoveryKeyState(submitAction = AsyncData.Failure(Exception("A Failure"))), + aSecureBackupEnterRecoveryKeyState(submitAction = AsyncAction.Loading), + aSecureBackupEnterRecoveryKeyState(submitAction = AsyncAction.Failure(Exception("A Failure"))), ) } fun aSecureBackupEnterRecoveryKeyState( recoveryKey: String = aFormattedRecoveryKey(), isSubmitEnabled: Boolean = recoveryKey.isNotEmpty(), - submitAction: AsyncData = AsyncData.Uninitialized, + submitAction: AsyncAction = AsyncAction.Uninitialized, ) = SecureBackupEnterRecoveryKeyState( recoveryKeyViewState = RecoveryKeyViewState( recoveryKeyUserStory = RecoveryKeyUserStory.Enter, 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 d5eda2c15a..f18937711c 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 @@ -29,7 +29,7 @@ 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.designsystem.atomic.pages.FlowStepPage -import io.element.android.libraries.designsystem.components.async.AsyncView +import io.element.android.libraries.designsystem.components.async.AsyncActionView 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 @@ -43,7 +43,7 @@ fun SecureBackupEnterRecoveryKeyView( onBackClicked: () -> Unit, modifier: Modifier = Modifier, ) { - AsyncView( + AsyncActionView( async = state.submitAction, onSuccess = { onDone() }, showProgressDialog = false, diff --git a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenterTest.kt b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenterTest.kt index 32847fc66c..9453e9e660 100644 --- a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenterTest.kt +++ b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenterTest.kt @@ -20,7 +20,7 @@ import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.encryption.BackupState import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.test.core.aBuildMeta @@ -42,7 +42,7 @@ class SecureBackupDisablePresenterTest { }.test { val initialState = awaitItem() assertThat(initialState.backupState).isEqualTo(BackupState.UNKNOWN) - assertThat(initialState.disableAction).isEqualTo(AsyncData.Uninitialized) + assertThat(initialState.disableAction).isEqualTo(AsyncAction.Uninitialized) assertThat(initialState.showConfirmationDialog).isFalse() assertThat(initialState.appName).isEqualTo("Element") } @@ -80,9 +80,9 @@ class SecureBackupDisablePresenterTest { skipItems(1) val loadingState = awaitItem() assertThat(loadingState.showConfirmationDialog).isFalse() - assertThat(loadingState.disableAction).isInstanceOf(AsyncData.Loading::class.java) + assertThat(loadingState.disableAction).isInstanceOf(AsyncAction.Loading::class.java) val finalState = awaitItem() - assertThat(finalState.disableAction).isEqualTo(AsyncData.Success(Unit)) + assertThat(finalState.disableAction).isEqualTo(AsyncAction.Success(Unit)) } } @@ -106,12 +106,12 @@ class SecureBackupDisablePresenterTest { skipItems(1) val loadingState = awaitItem() assertThat(loadingState.showConfirmationDialog).isFalse() - assertThat(loadingState.disableAction).isInstanceOf(AsyncData.Loading::class.java) + assertThat(loadingState.disableAction).isInstanceOf(AsyncAction.Loading::class.java) val errorState = awaitItem() - assertThat(errorState.disableAction).isInstanceOf(AsyncData.Failure::class.java) + assertThat(errorState.disableAction).isInstanceOf(AsyncAction.Failure::class.java) errorState.eventSink(SecureBackupDisableEvents.DismissDialogs) val finalState = awaitItem() - assertThat(finalState.disableAction).isEqualTo(AsyncData.Uninitialized) + assertThat(finalState.disableAction).isEqualTo(AsyncAction.Uninitialized) } } diff --git a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenterTest.kt b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenterTest.kt index 50da0728c4..3991fe306c 100644 --- a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenterTest.kt +++ b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenterTest.kt @@ -23,7 +23,7 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyUserStory import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState import io.element.android.features.securebackup.impl.tools.RecoveryKeyTools -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService @@ -44,7 +44,7 @@ class SecureBackupEnterRecoveryKeyPresenterTest { }.test { val initialState = awaitItem() assertThat(initialState.isSubmitEnabled).isFalse() - assertThat(initialState.submitAction).isEqualTo(AsyncData.Uninitialized) + assertThat(initialState.submitAction).isEqualTo(AsyncAction.Uninitialized) assertThat(initialState.recoveryKeyViewState).isEqualTo( RecoveryKeyViewState( recoveryKeyUserStory = RecoveryKeyUserStory.Enter, @@ -76,22 +76,22 @@ class SecureBackupEnterRecoveryKeyPresenterTest { encryptionService.givenRecoverFailure(AN_EXCEPTION) withRecoveryKeyState.eventSink(SecureBackupEnterRecoveryKeyEvents.Submit) val loadingState = awaitItem() - assertThat(loadingState.submitAction).isEqualTo(AsyncData.Loading()) + assertThat(loadingState.submitAction).isEqualTo(AsyncAction.Loading) assertThat(loadingState.isSubmitEnabled).isFalse() val errorState = awaitItem() - assertThat(errorState.submitAction).isEqualTo(AsyncData.Failure(AN_EXCEPTION)) + assertThat(errorState.submitAction).isEqualTo(AsyncAction.Failure(AN_EXCEPTION)) assertThat(errorState.isSubmitEnabled).isFalse() errorState.eventSink(SecureBackupEnterRecoveryKeyEvents.ClearDialog) val clearedState = awaitItem() - assertThat(clearedState.submitAction).isEqualTo(AsyncData.Uninitialized) + assertThat(clearedState.submitAction).isEqualTo(AsyncAction.Uninitialized) assertThat(clearedState.isSubmitEnabled).isTrue() encryptionService.givenRecoverFailure(null) clearedState.eventSink(SecureBackupEnterRecoveryKeyEvents.Submit) val loadingState2 = awaitItem() - assertThat(loadingState2.submitAction).isEqualTo(AsyncData.Loading()) + assertThat(loadingState2.submitAction).isEqualTo(AsyncAction.Loading) assertThat(loadingState2.isSubmitEnabled).isFalse() val finalState = awaitItem() - assertThat(finalState.submitAction).isEqualTo(AsyncData.Success(Unit)) + assertThat(finalState.submitAction).isEqualTo(AsyncAction.Success(Unit)) assertThat(finalState.isSubmitEnabled).isFalse() } } 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/AsyncActionProvider.kt similarity index 65% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncProvider.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncActionProvider.kt index ae090739ce..d74f0de5ca 100644 --- 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/AsyncActionProvider.kt @@ -17,14 +17,15 @@ package io.element.android.libraries.designsystem.components.async import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction -open class AsyncProvider : PreviewParameterProvider> { - override val values: Sequence> +open class AsyncActionProvider : PreviewParameterProvider> { + override val values: Sequence> get() = sequenceOf( - AsyncData.Uninitialized, - AsyncData.Loading(), - AsyncData.Failure(Exception("An error occurred")), - AsyncData.Success(Unit), + AsyncAction.Uninitialized, + AsyncAction.Confirming, + AsyncAction.Loading, + AsyncAction.Failure(Exception("An error occurred")), + AsyncAction.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/AsyncActionView.kt similarity index 62% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncView.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncActionView.kt index b58c1b3e2c..fb74ecd975 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/AsyncActionView.kt @@ -18,40 +18,55 @@ package io.element.android.libraries.designsystem.components.async import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter -import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncAction 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 +import io.element.android.libraries.ui.strings.CommonStrings /** - * Render an Async object. + * Render an AsyncAction 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: AsyncData, +fun AsyncActionView( + async: AsyncAction, onSuccess: (T) -> Unit, onErrorDismiss: () -> Unit, + showConfirmationDialog: Boolean = false, + confirmationText: String? = null, + confirmationSubmit: String? = null, + onConfirmation: (() -> Unit)? = null, showProgressDialog: Boolean = true, progressText: String? = null, errorTitle: @Composable (Throwable) -> String = { ErrorDialogDefaults.title }, errorMessage: @Composable (Throwable) -> String = { it.message ?: it.toString() }, onRetry: (() -> Unit)? = null, ) { - AsyncView( + AsyncActionView( async = async, onSuccess = onSuccess, onErrorDismiss = onErrorDismiss, + confirmingDialog = { + if (showConfirmationDialog) { + AsyncActionViewDefaults.ConfirmationDialog( + confirmationText = confirmationText, + confirmationSubmit = confirmationSubmit, + onConfirmation = onConfirmation, + ) + } + }, progressDialog = { if (showProgressDialog) { - AsyncViewDefaults.ProgressDialog(progressText) + AsyncActionViewDefaults.ProgressDialog(progressText) } }, errorTitle = errorTitle, @@ -61,19 +76,21 @@ fun AsyncView( } @Composable -fun AsyncView( - async: AsyncData, +fun AsyncActionView( + async: AsyncAction, onSuccess: (T) -> Unit, onErrorDismiss: () -> Unit, - progressDialog: @Composable () -> Unit = { AsyncViewDefaults.ProgressDialog() }, + confirmingDialog: @Composable () -> Unit = { AsyncActionViewDefaults.ConfirmationDialog() }, + progressDialog: @Composable () -> Unit = { AsyncActionViewDefaults.ProgressDialog() }, errorTitle: @Composable (Throwable) -> String = { ErrorDialogDefaults.title }, errorMessage: @Composable (Throwable) -> String = { it.message ?: it.toString() }, onRetry: (() -> Unit)? = null, ) { when (async) { - AsyncData.Uninitialized -> Unit - is AsyncData.Loading -> progressDialog() - is AsyncData.Failure -> { + AsyncAction.Uninitialized -> Unit + AsyncAction.Confirming -> confirmingDialog() + is AsyncAction.Loading -> progressDialog() + is AsyncAction.Failure -> { if (onRetry == null) { ErrorDialog( title = errorTitle(async.error), @@ -89,7 +106,7 @@ fun AsyncView( ) } } - is AsyncData.Success -> { + is AsyncAction.Success -> { LaunchedEffect(async) { onSuccess(async.data) } @@ -97,7 +114,23 @@ fun AsyncView( } } -object AsyncViewDefaults { +object AsyncActionViewDefaults { + @Composable + fun ConfirmationDialog( + confirmationText: String? = null, + confirmationSubmit: String? = null, + onConfirmation: (() -> Unit)? = null, + onDismiss: (() -> Unit)? = null, + ) { + io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog( + content = confirmationText.orEmpty(), + onSubmitClicked = onConfirmation ?: {}, + onDismiss = onDismiss ?: {}, + submitText = confirmationSubmit ?: stringResource(CommonStrings.action_continue), + cancelText = stringResource(CommonStrings.action_cancel), + ) + } + @Composable fun ProgressDialog(progressText: String? = null) { ProgressDialog( @@ -108,10 +141,10 @@ object AsyncViewDefaults { @PreviewsDayNight @Composable -internal fun AsyncViewPreview( - @PreviewParameter(AsyncProvider::class) async: AsyncData, +internal fun AsyncActionViewPreview( + @PreviewParameter(AsyncActionProvider::class) async: AsyncAction, ) = ElementPreview { - AsyncView( + AsyncActionView( async = async, onSuccess = {}, onErrorDismiss = {},