From 082fa1e69ee884f766975b08db420fbbfeb07713 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Thu, 29 Sep 2022 10:27:13 +0200 Subject: [PATCH] Adding confirmation dialog for all type of sessions --- .../v2/overview/SessionOverviewAction.kt | 2 +- .../v2/overview/SessionOverviewFragment.kt | 38 ++++++++++++++++--- .../v2/overview/SessionOverviewViewEvent.kt | 1 - .../v2/overview/SessionOverviewViewModel.kt | 13 ++----- .../overview/SessionOverviewViewModelTest.kt | 28 ++------------ 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewAction.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewAction.kt index c0d428b951..42e79ac89f 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewAction.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewAction.kt @@ -20,7 +20,7 @@ import im.vector.app.core.platform.VectorViewModelAction sealed class SessionOverviewAction : VectorViewModelAction { object VerifySession : SessionOverviewAction() - object SignoutSession : SessionOverviewAction() + object SignoutOtherSession : SessionOverviewAction() object SsoAuthDone : SessionOverviewAction() data class PasswordAuthDone(val password: String) : SessionOverviewAction() object ReAuthCancelled : SessionOverviewAction() diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt index 341b0233b7..4af4913183 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt @@ -28,6 +28,7 @@ import androidx.core.view.isVisible import com.airbnb.mvrx.Success import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState +import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.date.VectorDateFormatter @@ -42,6 +43,7 @@ import im.vector.app.features.crypto.recover.SetupMode import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState import im.vector.app.features.workers.signout.SignOutUiWorker import org.matrix.android.sdk.api.auth.data.LoginFlowTypes +import org.matrix.android.sdk.api.extensions.orFalse import javax.inject.Inject /** @@ -87,17 +89,12 @@ class SessionOverviewFragment : navigator.open4SSetup(requireActivity(), SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET) } is SessionOverviewViewEvent.RequestReAuth -> askForReAuthentication(it) - SessionOverviewViewEvent.ConfirmSignoutCurrentSession -> confirmSignoutCurrentSession() SessionOverviewViewEvent.SignoutSuccess -> viewNavigator.goBack(requireActivity()) is SessionOverviewViewEvent.SignoutError -> showFailure(it.error) } } } - private fun confirmSignoutCurrentSession() { - activity?.let { SignOutUiWorker(it).perform() } - } - private fun initSessionInfoView() { views.sessionOverviewInfo.onLearnMoreClickListener = { Toast.makeText(context, "Learn more verification status", Toast.LENGTH_LONG).show() @@ -112,10 +109,39 @@ class SessionOverviewFragment : private fun initSignoutButton() { views.sessionOverviewSignout.debouncedClicks { - viewModel.handle(SessionOverviewAction.SignoutSession) + confirmSignoutSession() } } + private fun confirmSignoutSession() = withState(viewModel) { state -> + if (state.deviceInfo.invoke()?.isCurrentDevice.orFalse()) { + confirmSignoutCurrentSession() + } else { + confirmSignoutOtherSession() + } + } + + private fun confirmSignoutCurrentSession() { + activity?.let { SignOutUiWorker(it).perform() } + } + + private fun confirmSignoutOtherSession() { + activity?.let { + MaterialAlertDialogBuilder(it) + .setTitle(R.string.action_sign_out) + .setMessage(R.string.action_sign_out_confirmation_simple) + .setPositiveButton(R.string.action_sign_out) { _, _ -> + signoutSession() + } + .setNegativeButton(R.string.action_cancel, null) + .show() + } + } + + private fun signoutSession() { + viewModel.handle(SessionOverviewAction.SignoutOtherSession) + } + override fun onDestroyView() { cleanUpSessionInfoView() super.onDestroyView() diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewEvent.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewEvent.kt index 0d8a2ac8af..4ff31d1a81 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewEvent.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewEvent.kt @@ -28,7 +28,6 @@ sealed class SessionOverviewViewEvent : VectorViewEvents { val lastErrorCode: String? ) : SessionOverviewViewEvent() - object ConfirmSignoutCurrentSession : SessionOverviewViewEvent() object SignoutSuccess : SessionOverviewViewEvent() data class SignoutError(val error: Throwable) : SessionOverviewViewEvent() } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt index 717c51978a..bd5c7725eb 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt @@ -97,7 +97,7 @@ class SessionOverviewViewModel @AssistedInject constructor( override fun handle(action: SessionOverviewAction) { when (action) { is SessionOverviewAction.VerifySession -> handleVerifySessionAction() - SessionOverviewAction.SignoutSession -> handleSignoutSession() + SessionOverviewAction.SignoutOtherSession -> handleSignoutOtherSession() SessionOverviewAction.SsoAuthDone -> handleSsoAuthDone() is SessionOverviewAction.PasswordAuthDone -> handlePasswordAuthDone(action) SessionOverviewAction.ReAuthCancelled -> handleReAuthCancelled() @@ -127,18 +127,13 @@ class SessionOverviewViewModel @AssistedInject constructor( _viewEvents.post(SessionOverviewViewEvent.ShowVerifyOtherSession(deviceId)) } - private fun handleSignoutSession() = withState { state -> - if (state.deviceInfo.invoke()?.isCurrentDevice.orFalse()) { - handleSignoutCurrentSession() - } else { + private fun handleSignoutOtherSession() = withState { state -> + // signout process for current session is not handled here + if (!state.deviceInfo.invoke()?.isCurrentDevice.orFalse()) { handleSignoutOtherSession(state.deviceId) } } - private fun handleSignoutCurrentSession() { - _viewEvents.post(SessionOverviewViewEvent.ConfirmSignoutCurrentSession) - } - private fun handleSignoutOtherSession(deviceId: String) { viewModelScope.launch { setLoading(true) diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt index c05c6daa3f..4f3cc66d63 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt @@ -199,26 +199,6 @@ class SessionOverviewViewModelTest { .finish() } - @Test - fun `given current session when handling signout action then confirmation event is posted`() { - // Given - val deviceFullInfo = mockk() - every { deviceFullInfo.isCurrentDevice } returns true - every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) - val signoutAction = SessionOverviewAction.SignoutSession - givenCurrentSessionIsTrusted() - - // When - val viewModel = createViewModel() - val viewModelTest = viewModel.test() - viewModel.handle(signoutAction) - - // Then - viewModelTest - .assertEvent { it is SessionOverviewViewEvent.ConfirmSignoutCurrentSession } - .finish() - } - @Test fun `given another session and no reAuth is needed when handling signout action then signout process is performed`() { // Given @@ -227,7 +207,7 @@ class SessionOverviewViewModelTest { every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) givenSignoutSuccess(A_SESSION_ID_1) every { refreshDevicesUseCase.execute() } just runs - val signoutAction = SessionOverviewAction.SignoutSession + val signoutAction = SessionOverviewAction.SignoutOtherSession givenCurrentSessionIsTrusted() val expectedViewState = SessionOverviewViewState( deviceId = A_SESSION_ID_1, @@ -263,7 +243,7 @@ class SessionOverviewViewModelTest { every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) val serverError = Failure.OtherServerError(errorBody = "", httpCode = HttpsURLConnection.HTTP_UNAUTHORIZED) givenSignoutError(A_SESSION_ID_1, serverError) - val signoutAction = SessionOverviewAction.SignoutSession + val signoutAction = SessionOverviewAction.SignoutOtherSession givenCurrentSessionIsTrusted() val expectedViewState = SessionOverviewViewState( deviceId = A_SESSION_ID_1, @@ -297,7 +277,7 @@ class SessionOverviewViewModelTest { every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) val error = Exception() givenSignoutError(A_SESSION_ID_1, error) - val signoutAction = SessionOverviewAction.SignoutSession + val signoutAction = SessionOverviewAction.SignoutOtherSession givenCurrentSessionIsTrusted() val expectedViewState = SessionOverviewViewState( deviceId = A_SESSION_ID_1, @@ -330,7 +310,7 @@ class SessionOverviewViewModelTest { every { deviceFullInfo.isCurrentDevice } returns false every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) val reAuthNeeded = givenSignoutReAuthNeeded(A_SESSION_ID_1) - val signoutAction = SessionOverviewAction.SignoutSession + val signoutAction = SessionOverviewAction.SignoutOtherSession givenCurrentSessionIsTrusted() val expectedPendingAuth = DefaultBaseAuth(session = reAuthNeeded.flowResponse.session) val expectedReAuthEvent = SessionOverviewViewEvent.RequestReAuth(reAuthNeeded.flowResponse, reAuthNeeded.errCode)