Adds login type handling to SoftLogoutController

This commit is contained in:
ericdecanini 2022-03-04 14:51:39 +01:00
parent 2fda593c3c
commit 92f87a3a5a
3 changed files with 78 additions and 58 deletions

View file

@ -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() }
}
}

View file

@ -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,
)
}
}

View file

@ -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<LoginMode> = 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 {