From 136185272139a1f87ca14eeee2eb24884950ec99 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 29 Jun 2022 14:11:39 +0100 Subject: [PATCH] triggering an initial enabled state when using associateContentStateWith and extracts the resetting of errors on content change to an extension --- .../app/core/extensions/TextInputLayout.kt | 15 +++++++++++++-- .../FtueAuthCombinedServerSelectionFragment.kt | 9 ++------- .../ftueauth/FtueAuthEmailEntryFragment.kt | 16 +++------------- .../FtueAuthResetPasswordEmailEntryFragment.kt | 15 +++------------ .../FtueAuthResetPasswordEntryFragment.kt | 10 ++-------- 5 files changed, 23 insertions(+), 42 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/extensions/TextInputLayout.kt b/vector/src/main/java/im/vector/app/core/extensions/TextInputLayout.kt index 41016365c0..40019c5d64 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/TextInputLayout.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/TextInputLayout.kt @@ -19,9 +19,13 @@ package im.vector.app.core.extensions import android.text.Editable import android.view.View import android.view.inputmethod.EditorInfo +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.lifecycleScope import com.google.android.material.textfield.TextInputLayout import im.vector.app.core.platform.SimpleTextWatcher +import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach import reactivecircus.flowbinding.android.widget.textChanges fun TextInputLayout.editText() = this.editText!! @@ -37,11 +41,18 @@ fun TextInputLayout.content() = editText().text.toString() fun TextInputLayout.hasContent() = !editText().text.isNullOrEmpty() -fun TextInputLayout.associateContentStateWith(button: View) { +fun TextInputLayout.clearErrorOnChange(lifecycleOwner: LifecycleOwner) { + editText().textChanges() + .onEach { error = null } + .launchIn(lifecycleOwner.lifecycleScope) +} + +fun TextInputLayout.associateContentStateWith(button: View, enabledPredicate: (String) -> Boolean = { it.isNotEmpty() }) { + button.isEnabled = enabledPredicate(content()) editText().addTextChangedListener(object : SimpleTextWatcher() { override fun afterTextChanged(s: Editable) { val newContent = s.toString() - button.isEnabled = newContent.isNotEmpty() + button.isEnabled = enabledPredicate(newContent) } }) } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedServerSelectionFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedServerSelectionFragment.kt index b689f40837..bc44a7dbdb 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedServerSelectionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedServerSelectionFragment.kt @@ -21,8 +21,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.inputmethod.EditorInfo -import androidx.lifecycle.lifecycleScope import im.vector.app.R +import im.vector.app.core.extensions.clearErrorOnChange import im.vector.app.core.extensions.content import im.vector.app.core.extensions.editText import im.vector.app.core.extensions.realignPercentagesToParent @@ -34,10 +34,7 @@ import im.vector.app.databinding.FragmentFtueServerSelectionCombinedBinding import im.vector.app.features.onboarding.OnboardingAction import im.vector.app.features.onboarding.OnboardingViewEvents import im.vector.app.features.onboarding.OnboardingViewState -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.failure.isHomeserverUnavailable -import reactivecircus.flowbinding.android.widget.textChanges import javax.inject.Inject class FtueAuthCombinedServerSelectionFragment @Inject constructor() : AbstractFtueAuthFragment() { @@ -66,9 +63,7 @@ class FtueAuthCombinedServerSelectionFragment @Inject constructor() : AbstractFt } views.chooseServerGetInTouch.debouncedClicks { openUrlInExternalBrowser(requireContext(), getString(R.string.ftue_ems_url)) } views.chooseServerSubmit.debouncedClicks { updateServerUrl() } - views.chooseServerInput.editText().textChanges() - .onEach { views.chooseServerInput.error = null } - .launchIn(viewLifecycleOwner.lifecycleScope) + views.chooseServerInput.clearErrorOnChange(viewLifecycleOwner) } private fun updateServerUrl() { diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthEmailEntryFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthEmailEntryFragment.kt index ea376709f5..523d576120 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthEmailEntryFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthEmailEntryFragment.kt @@ -20,19 +20,15 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.lifecycle.lifecycleScope import im.vector.app.core.extensions.associateContentStateWith +import im.vector.app.core.extensions.clearErrorOnChange import im.vector.app.core.extensions.content -import im.vector.app.core.extensions.editText import im.vector.app.core.extensions.isEmail import im.vector.app.core.extensions.setOnImeDoneListener import im.vector.app.databinding.FragmentFtueEmailInputBinding import im.vector.app.features.onboarding.OnboardingAction import im.vector.app.features.onboarding.RegisterAction -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.auth.registration.RegisterThreePid -import reactivecircus.flowbinding.android.widget.textChanges import javax.inject.Inject class FtueAuthEmailEntryFragment @Inject constructor() : AbstractFtueAuthFragment() { @@ -47,16 +43,10 @@ class FtueAuthEmailEntryFragment @Inject constructor() : AbstractFtueAuthFragmen } private fun setupViews() { - views.emailEntryInput.associateContentStateWith(button = views.emailEntrySubmit) + views.emailEntryInput.associateContentStateWith(button = views.emailEntrySubmit, enabledPredicate = { it.isEmail() }) views.emailEntryInput.setOnImeDoneListener { updateEmail() } + views.emailEntryInput.clearErrorOnChange(viewLifecycleOwner) views.emailEntrySubmit.debouncedClicks { updateEmail() } - - views.emailEntryInput.editText().textChanges() - .onEach { - views.emailEntryInput.error = null - views.emailEntrySubmit.isEnabled = it.isEmail() - } - .launchIn(viewLifecycleOwner.lifecycleScope) } private fun updateEmail() { diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordEmailEntryFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordEmailEntryFragment.kt index 5119ba6179..e8110569a2 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordEmailEntryFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordEmailEntryFragment.kt @@ -20,18 +20,14 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint import im.vector.app.core.extensions.associateContentStateWith +import im.vector.app.core.extensions.clearErrorOnChange import im.vector.app.core.extensions.content -import im.vector.app.core.extensions.editText import im.vector.app.core.extensions.isEmail import im.vector.app.core.extensions.setOnImeDoneListener import im.vector.app.databinding.FragmentFtueResetPasswordEmailInputBinding import im.vector.app.features.onboarding.OnboardingAction -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import reactivecircus.flowbinding.android.widget.textChanges @AndroidEntryPoint class FtueAuthResetPasswordEmailEntryFragment : AbstractFtueAuthFragment() { @@ -46,14 +42,9 @@ class FtueAuthResetPasswordEmailEntryFragment : AbstractFtueAuthFragment() { @@ -51,9 +47,7 @@ class FtueAuthResetPasswordEntryFragment : AbstractFtueAuthFragment