replacing async reset password,mail and homeserver requests with shared isLoading with error view events

This commit is contained in:
Adam Brown 2022-03-08 12:00:42 +00:00
parent 2227df479c
commit 7d80cfed0b
5 changed files with 44 additions and 95 deletions

View file

@ -18,11 +18,7 @@ package im.vector.app.features.onboarding
import android.content.Context
import android.net.Uri
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.MavericksViewModelFactory
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.Uninitialized
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@ -249,8 +245,8 @@ class OnboardingViewModel @AssistedInject constructor(
val result = safeLoginWizard.loginWithToken(action.loginToken)
onSessionCreated(result, isAccountCreated = false)
} catch (failure: Throwable) {
_viewEvents.post(OnboardingViewEvents.Failure(failure))
setState { copy(isLoading = false) }
_viewEvents.post(OnboardingViewEvents.Failure(failure))
}
}
}
@ -310,7 +306,7 @@ class OnboardingViewModel @AssistedInject constructor(
authenticationService.reset()
setState {
copy(
asyncHomeServerLoginFlowRequest = Uninitialized,
isLoading = false,
homeServerUrlFromUser = null,
homeServerUrl = null,
loginMode = LoginMode.Unknown,
@ -323,7 +319,7 @@ class OnboardingViewModel @AssistedInject constructor(
OnboardingAction.ResetSignMode -> {
setState {
copy(
asyncHomeServerLoginFlowRequest = Uninitialized,
isLoading = false,
signMode = SignMode.Unknown,
loginMode = LoginMode.Unknown,
loginModeSupportedTypes = emptyList()
@ -339,8 +335,7 @@ class OnboardingViewModel @AssistedInject constructor(
OnboardingAction.ResetResetPassword -> {
setState {
copy(
asyncResetPassword = Uninitialized,
asyncResetMailConfirmed = Uninitialized,
isLoading = false,
resetPasswordEmail = null
)
}
@ -409,35 +404,23 @@ class OnboardingViewModel @AssistedInject constructor(
val safeLoginWizard = loginWizard
if (safeLoginWizard == null) {
setState {
copy(
asyncResetPassword = Fail(Throwable("Bad configuration")),
asyncResetMailConfirmed = Uninitialized
)
}
setState { copy(isLoading = false) }
_viewEvents.post(OnboardingViewEvents.Failure(Throwable("Bad configuration")))
} else {
setState {
copy(
asyncResetPassword = Loading(),
asyncResetMailConfirmed = Uninitialized
)
}
setState { copy(isLoading = true) }
currentJob = viewModelScope.launch {
try {
safeLoginWizard.resetPassword(action.email, action.newPassword)
} catch (failure: Throwable) {
setState {
copy(
asyncResetPassword = Fail(failure)
)
}
setState { copy(isLoading = false) }
_viewEvents.post(OnboardingViewEvents.Failure(failure))
return@launch
}
setState {
copy(
asyncResetPassword = Success(Unit),
isLoading = false,
resetPasswordEmail = action.email
)
}
@ -451,34 +434,22 @@ class OnboardingViewModel @AssistedInject constructor(
val safeLoginWizard = loginWizard
if (safeLoginWizard == null) {
setState {
copy(
asyncResetPassword = Uninitialized,
asyncResetMailConfirmed = Fail(Throwable("Bad configuration"))
)
}
setState { copy(isLoading = false) }
_viewEvents.post(OnboardingViewEvents.Failure(Throwable("Bad configuration")))
} else {
setState {
copy(
asyncResetPassword = Uninitialized,
asyncResetMailConfirmed = Loading()
)
}
setState { copy(isLoading = false) }
currentJob = viewModelScope.launch {
try {
safeLoginWizard.resetPasswordMailConfirmed()
} catch (failure: Throwable) {
setState {
copy(
asyncResetMailConfirmed = Fail(failure)
)
}
setState { copy(isLoading = false) }
_viewEvents.post(OnboardingViewEvents.Failure(failure))
return@launch
}
setState {
copy(
asyncResetMailConfirmed = Success(Unit),
isLoading = false,
resetPasswordEmail = null
)
}
@ -560,9 +531,9 @@ class OnboardingViewModel @AssistedInject constructor(
when (failure) {
is MatrixIdFailure.InvalidMatrixId,
is Failure.UnrecognizedCertificateFailure -> {
setState { copy(isLoading = false) }
// Display this error in a dialog
_viewEvents.post(OnboardingViewEvents.Failure(failure))
setState { copy(isLoading = false) }
}
else -> {
setState { copy(isLoading = false) }
@ -589,6 +560,7 @@ class OnboardingViewModel @AssistedInject constructor(
onSessionCreated(result, isAccountCreated = false)
} catch (failure: Throwable) {
setState { copy(isLoading = false) }
_viewEvents.post(OnboardingViewEvents.Failure(failure))
}
}
}
@ -692,7 +664,7 @@ class OnboardingViewModel @AssistedInject constructor(
setState {
copy(
asyncHomeServerLoginFlowRequest = Loading(),
isLoading = true,
// If user has entered https://matrix.org, ensure that server type is ServerType.MatrixOrg
// It is also useful to set the value again in the case of a certificate error on matrix.org
serverType = if (homeServerConnectionConfig.homeServerUri.toString() == matrixOrgUrl) {
@ -706,14 +678,14 @@ class OnboardingViewModel @AssistedInject constructor(
val data = try {
authenticationService.getLoginFlow(homeServerConnectionConfig)
} catch (failure: Throwable) {
_viewEvents.post(OnboardingViewEvents.Failure(failure))
setState {
copy(
asyncHomeServerLoginFlowRequest = Uninitialized,
isLoading = false,
// If we were trying to retrieve matrix.org login flow, also reset the serverType
serverType = if (serverType == ServerType.MatrixOrg) ServerType.Unknown else serverType
)
}
_viewEvents.post(OnboardingViewEvents.Failure(failure))
null
}
@ -734,7 +706,7 @@ class OnboardingViewModel @AssistedInject constructor(
setState {
copy(
asyncHomeServerLoginFlowRequest = Uninitialized,
isLoading = false,
homeServerUrlFromUser = homeServerConnectionConfig.homeServerUri.toString(),
homeServerUrl = data.homeServerUrl,
loginMode = loginMode,

View file

@ -18,20 +18,14 @@ package im.vector.app.features.onboarding
import android.net.Uri
import android.os.Parcelable
import com.airbnb.mvrx.Async
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.MavericksState
import com.airbnb.mvrx.PersistState
import com.airbnb.mvrx.Uninitialized
import im.vector.app.features.login.LoginMode
import im.vector.app.features.login.ServerType
import im.vector.app.features.login.SignMode
import kotlinx.parcelize.Parcelize
data class OnboardingViewState(
val asyncHomeServerLoginFlowRequest: Async<Unit> = Uninitialized,
val asyncResetPassword: Async<Unit> = Uninitialized,
val asyncResetMailConfirmed: Async<Unit> = Uninitialized,
val isLoading: Boolean = false,
@PersistState
@ -68,14 +62,7 @@ data class OnboardingViewState(
@PersistState
val personalizationState: PersonalizationState = PersonalizationState()
) : MavericksState {
fun legacyIsLoading(): Boolean {
return asyncHomeServerLoginFlowRequest is Loading ||
asyncResetPassword is Loading ||
asyncResetMailConfirmed is Loading
}
}
) : MavericksState
enum class OnboardingFlow {
SignIn,

View file

@ -21,8 +21,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.core.extensions.hideKeyboard
@ -53,10 +51,13 @@ class FtueAuthResetPasswordFragment @Inject constructor() : AbstractFtueAuthFrag
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupSubmitButton()
}
override fun showFailure(throwable: Throwable) {
views.resetPasswordEmailTil.error = errorFormatter.toHumanReadable(throwable)
}
private fun setupUi(state: OnboardingViewState) {
views.resetPasswordTitle.text = getString(R.string.login_reset_password_on, state.homeServerUrlFromUser.toReducedUrl())
}
@ -115,16 +116,9 @@ class FtueAuthResetPasswordFragment @Inject constructor() : AbstractFtueAuthFrag
override fun updateWithState(state: OnboardingViewState) {
setupUi(state)
when (state.asyncResetPassword) {
is Loading -> {
// Ensure new password is hidden
views.passwordField.hidePassword()
}
is Fail -> {
views.resetPasswordEmailTil.error = errorFormatter.toHumanReadable(state.asyncResetPassword.error)
}
else -> Unit
if (state.isLoading) {
// Ensure new password is hidden
views.passwordField.hidePassword()
}
}
}

View file

@ -20,7 +20,6 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.airbnb.mvrx.Fail
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
import im.vector.app.databinding.FragmentLoginResetPasswordMailConfirmationBinding
@ -58,23 +57,20 @@ class FtueAuthResetPasswordMailConfirmationFragment @Inject constructor() : Abst
override fun updateWithState(state: OnboardingViewState) {
setupUi(state)
}
when (state.asyncResetMailConfirmed) {
is Fail -> {
// Link in email not yet clicked ?
val message = if (state.asyncResetMailConfirmed.error.is401()) {
getString(R.string.auth_reset_password_error_unauthorized)
} else {
errorFormatter.toHumanReadable(state.asyncResetMailConfirmed.error)
}
MaterialAlertDialogBuilder(requireActivity())
.setTitle(R.string.dialog_title_error)
.setMessage(message)
.setPositiveButton(R.string.ok, null)
.show()
}
else -> Unit
override fun showFailure(throwable: Throwable) {
// Link in email not yet clicked ?
val message = if (throwable.is401()) {
getString(R.string.auth_reset_password_error_unauthorized)
} else {
errorFormatter.toHumanReadable(throwable)
}
MaterialAlertDialogBuilder(requireActivity())
.setTitle(R.string.dialog_title_error)
.setMessage(message)
.setPositiveButton(R.string.ok, null)
.show()
}
}

View file

@ -121,7 +121,7 @@ class FtueAuthVariant(
private fun updateWithState(viewState: OnboardingViewState) {
isForceLoginFallbackEnabled = viewState.isForceLoginFallbackEnabled
views.loginLoading.isVisible = viewState.isLoading || viewState.legacyIsLoading()
views.loginLoading.isVisible = viewState.isLoading
}
override fun setIsLoading(isLoading: Boolean) = Unit