diff --git a/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutAction.kt b/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutAction.kt index 254f65d622..07ba1f67e0 100644 --- a/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutAction.kt @@ -20,6 +20,7 @@ import im.vector.riotx.core.platform.VectorViewModelAction sealed class SoftLogoutAction : VectorViewModelAction { object RetryLoginFlow : SoftLogoutAction() + data class PasswordChanged(val password: String) : SoftLogoutAction() object TogglePassword : SoftLogoutAction() data class SignInAgain(val password: String) : SoftLogoutAction() diff --git a/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutController.kt b/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutController.kt index b95ef91ad9..49802ec0af 100644 --- a/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutController.kt +++ b/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutController.kt @@ -104,6 +104,8 @@ class SoftLogoutController @Inject constructor( id("passwordForm") stringProvider(stringProvider) passwordShown(state.passwordShown) + submitEnabled(state.submitEnabled) + onPasswordEdited { listener?.passwordEdited(it) } errorText((state.asyncLoginAction as? Fail)?.error?.let { errorFormatter.toHumanReadable(it) }) passwordRevealClickListener { listener?.revealPasswordClicked() } forgetPasswordClickListener { listener?.forgetPasswordClicked() } @@ -141,6 +143,7 @@ class SoftLogoutController @Inject constructor( interface Listener { fun retry() + fun passwordEdited(password: String) fun submit(password: String) fun ssoSubmit() fun clearData() diff --git a/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutFragment.kt b/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutFragment.kt index 4959217aee..a54590e93b 100644 --- a/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutFragment.kt @@ -72,6 +72,10 @@ class SoftLogoutFragment @Inject constructor( softLogoutViewModel.handle(SoftLogoutAction.RetryLoginFlow) } + override fun passwordEdited(password: String) { + softLogoutViewModel.handle(SoftLogoutAction.PasswordChanged(password)) + } + override fun submit(password: String) { cleanupUi() softLogoutViewModel.handle(SoftLogoutAction.SignInAgain(password)) diff --git a/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutViewModel.kt b/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutViewModel.kt index f2c31fe836..81512b709d 100644 --- a/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutViewModel.kt @@ -143,9 +143,19 @@ class SoftLogoutViewModel @AssistedInject constructor( override fun handle(action: SoftLogoutAction) { when (action) { - is SoftLogoutAction.RetryLoginFlow -> getSupportedLoginFlow() - is SoftLogoutAction.SignInAgain -> handleSignInAgain(action) - is SoftLogoutAction.TogglePassword -> handleTogglePassword() + is SoftLogoutAction.RetryLoginFlow -> getSupportedLoginFlow() + is SoftLogoutAction.SignInAgain -> handleSignInAgain(action) + is SoftLogoutAction.PasswordChanged -> handlePasswordChange(action) + is SoftLogoutAction.TogglePassword -> handleTogglePassword() + } + } + + private fun handlePasswordChange(action: SoftLogoutAction.PasswordChanged) { + setState { + copy( + asyncLoginAction = Uninitialized, + submitEnabled = action.password.isNotBlank() + ) } } diff --git a/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutViewState.kt b/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutViewState.kt index efa5565207..c0c97a1628 100644 --- a/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutViewState.kt +++ b/vector/src/main/java/im/vector/riotx/features/signout/SoftLogoutViewState.kt @@ -29,7 +29,8 @@ data class SoftLogoutViewState( val userId: String, val userDisplayName: String, val hasUnsavedKeys: Boolean, - val passwordShown: Boolean = false + val passwordShown: Boolean = false, + val submitEnabled: Boolean = false ) : MvRxState { fun isLoading(): Boolean { diff --git a/vector/src/main/java/im/vector/riotx/features/signout/epoxy/LoginPasswordFormItem.kt b/vector/src/main/java/im/vector/riotx/features/signout/epoxy/LoginPasswordFormItem.kt index 53d407c45c..12534ab6e9 100644 --- a/vector/src/main/java/im/vector/riotx/features/signout/epoxy/LoginPasswordFormItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/signout/epoxy/LoginPasswordFormItem.kt @@ -17,6 +17,7 @@ package im.vector.riotx.features.signout.epoxy import android.os.Build +import android.text.Editable import android.widget.Button import android.widget.ImageView import androidx.autofill.HintConstants @@ -28,17 +29,26 @@ import im.vector.riotx.R import im.vector.riotx.core.epoxy.VectorEpoxyHolder import im.vector.riotx.core.epoxy.VectorEpoxyModel import im.vector.riotx.core.extensions.showPassword +import im.vector.riotx.core.platform.SimpleTextWatcher import im.vector.riotx.core.resources.StringProvider @EpoxyModelClass(layout = R.layout.item_login_password_form) abstract class LoginPasswordFormItem : VectorEpoxyModel() { @EpoxyAttribute var passwordShown: Boolean = false + @EpoxyAttribute var submitEnabled: Boolean = false @EpoxyAttribute var errorText: String? = null @EpoxyAttribute lateinit var stringProvider: StringProvider @EpoxyAttribute var passwordRevealClickListener: (() -> Unit)? = null @EpoxyAttribute var forgetPasswordClickListener: (() -> Unit)? = null @EpoxyAttribute var submitClickListener: ((String) -> Unit)? = null + @EpoxyAttribute var onPasswordEdited: ((String) -> Unit)? = null + + private val textChangeListener = object : SimpleTextWatcher() { + override fun afterTextChanged(s: Editable) { + onPasswordEdited?.invoke(s.toString()) + } + } override fun bind(holder: Holder) { super.bind(holder) @@ -48,7 +58,14 @@ abstract class LoginPasswordFormItem : VectorEpoxyModel