diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt index 25011ebc8a..6742894fde 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt @@ -19,7 +19,9 @@ package im.vector.app.features.signout.soft import com.airbnb.epoxy.EpoxyController import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Incomplete +import com.airbnb.mvrx.Loading import com.airbnb.mvrx.Success +import com.airbnb.mvrx.Uninitialized import im.vector.app.R import im.vector.app.core.epoxy.loadingItem import im.vector.app.core.error.ErrorFormatter @@ -34,7 +36,7 @@ import im.vector.app.features.signout.soft.epoxy.loginRedButtonItem import im.vector.app.features.signout.soft.epoxy.loginTextItem import im.vector.app.features.signout.soft.epoxy.loginTitleItem import im.vector.app.features.signout.soft.epoxy.loginTitleSmallItem -import timber.log.Timber +import org.matrix.android.sdk.internal.auth.login.LoginType import javax.inject.Inject class SoftLogoutController @Inject constructor( @@ -87,61 +89,74 @@ class SoftLogoutController @Inject constructor( } } - private fun buildForm(state: SoftLogoutViewState) { + private fun buildForm(state: SoftLogoutViewState) = when (state.asyncHomeServerLoginFlowRequest) { + is Incomplete -> buildLoadingItem() + is Fail -> buildLoginErrorWithRetryItem(state.asyncHomeServerLoginFlowRequest.error) + is Success -> buildLoginSuccessItem(state) + is Loading, Uninitialized -> Unit + } + + private fun buildLoadingItem() { + loadingItem { + id("loading") + } + } + + private fun buildLoginErrorWithRetryItem(error: Throwable) { val host = this - when (state.asyncHomeServerLoginFlowRequest) { - is Incomplete -> { - loadingItem { - id("loading") - } - } - is Fail -> { - loginErrorWithRetryItem { - id("errorRetry") - text(host.errorFormatter.toHumanReadable(state.asyncHomeServerLoginFlowRequest.error)) - listener { host.listener?.retry() } - } - } - is Success -> { - val loginMode = state.asyncHomeServerLoginFlowRequest.invoke() - Timber.i("Login Mode: $loginMode") - when (state.asyncHomeServerLoginFlowRequest.invoke()) { - LoginMode.Password -> { - loginPasswordFormItem { - id("passwordForm") - stringProvider(host.stringProvider) - passwordValue(state.enteredPassword) - submitEnabled(state.enteredPassword.isNotEmpty()) - onPasswordEdited { host.listener?.passwordEdited(it) } - errorText((state.asyncLoginAction as? Fail)?.error?.let { host.errorFormatter.toHumanReadable(it) }) - forgetPasswordClickListener { host.listener?.forgetPasswordClicked() } - submitClickListener { host.listener?.submit() } - } - } - is LoginMode.Sso -> { - loginCenterButtonItem { - id("sso") - text(host.stringProvider.getString(R.string.login_signin_sso)) - listener { host.listener?.signinFallbackSubmit() } - } - } - is LoginMode.SsoAndPassword -> { - loginCenterButtonItem { - id("sso") - text(host.stringProvider.getString(R.string.login_signin_sso)) - listener { host.listener?.signinFallbackSubmit() } - } - } - LoginMode.Unsupported -> { - loginCenterButtonItem { - id("fallback") - text(host.stringProvider.getString(R.string.login_signin)) - listener { host.listener?.signinFallbackSubmit() } - } - } - LoginMode.Unknown -> Unit // Should not happen - } - } + loginErrorWithRetryItem { + id("errorRetry") + text(host.errorFormatter.toHumanReadable(error)) + listener { host.listener?.retry() } + } + } + + private fun buildLoginSuccessItem(state: SoftLogoutViewState) = when (state.asyncHomeServerLoginFlowRequest.invoke()) { + LoginMode.Password -> buildLoginPasswordForm(state) + is LoginMode.Sso -> buildLoginSSOForm() + is LoginMode.SsoAndPassword -> disambiguateLoginSSOAndPasswordForm(state) + LoginMode.Unsupported -> buildLoginUnsupportedForm() + LoginMode.Unknown, null -> Unit // Should not happen + } + + private fun buildLoginPasswordForm(state: SoftLogoutViewState) { + val host = this + loginPasswordFormItem { + id("passwordForm") + stringProvider(host.stringProvider) + passwordValue(state.enteredPassword) + submitEnabled(state.enteredPassword.isNotEmpty()) + onPasswordEdited { host.listener?.passwordEdited(it) } + errorText((state.asyncLoginAction as? Fail)?.error?.let { host.errorFormatter.toHumanReadable(it) }) + forgetPasswordClickListener { host.listener?.forgetPasswordClicked() } + submitClickListener { host.listener?.submit() } + } + } + + private fun buildLoginSSOForm() { + val host = this + loginCenterButtonItem { + id("sso") + text(host.stringProvider.getString(R.string.login_signin_sso)) + listener { host.listener?.signinFallbackSubmit() } + } + } + + private fun disambiguateLoginSSOAndPasswordForm(state: SoftLogoutViewState) { + when (state.loginType) { + LoginType.PASSWORD -> buildLoginPasswordForm(state) + LoginType.SSO -> buildLoginSSOForm() + LoginType.UNSUPPORTED -> buildLoginUnsupportedForm() + LoginType.UNKNOWN -> Unit + } + } + + private fun buildLoginUnsupportedForm() { + val host = this + loginCenterButtonItem { + id("fallback") + text(host.stringProvider.getString(R.string.login_signin)) + listener { host.listener?.signinFallbackSubmit() } } } diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt index 00422d8872..dcc18ea088 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt @@ -37,6 +37,7 @@ import kotlinx.coroutines.launch import org.matrix.android.sdk.api.auth.AuthenticationService import org.matrix.android.sdk.api.auth.data.LoginFlowTypes import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.internal.auth.login.LoginType import timber.log.Timber /** @@ -69,7 +70,8 @@ class SoftLogoutViewModel @AssistedInject constructor( userId = userId, deviceId = session.sessionParams.deviceId.orEmpty(), userDisplayName = session.getUser(userId)?.displayName ?: userId, - hasUnsavedKeys = session.hasUnsavedKeys() + hasUnsavedKeys = session.hasUnsavedKeys(), + loginType = session.sessionParams.loginType, ) } else { SoftLogoutViewState( @@ -77,7 +79,8 @@ class SoftLogoutViewModel @AssistedInject constructor( userId = "", deviceId = "", userDisplayName = "", - hasUnsavedKeys = false + hasUnsavedKeys = false, + loginType = LoginType.UNKNOWN, ) } } diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewState.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewState.kt index 511711ab2f..f13b089ac5 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewState.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewState.kt @@ -22,6 +22,7 @@ import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import im.vector.app.features.login.LoginMode +import org.matrix.android.sdk.internal.auth.login.LoginType data class SoftLogoutViewState( val asyncHomeServerLoginFlowRequest: Async = Uninitialized, @@ -31,7 +32,8 @@ data class SoftLogoutViewState( val deviceId: String, val userDisplayName: String, val hasUnsavedKeys: Boolean, - val enteredPassword: String = "" + val loginType: LoginType, + val enteredPassword: String = "", ) : MavericksState { fun isLoading(): Boolean {