From 97ffbff89ae8f51ead6de94404c847bf018897f0 Mon Sep 17 00:00:00 2001 From: Kirill Kamakin Date: Mon, 4 Apr 2022 21:19:57 +0500 Subject: [PATCH 1/2] Trim e-mail and username to ease the login process Spaces aren't visible in EditText and it's possible to get authentication errors because of that invisible space. --- .../mealient/extensions/ViewExtensions.kt | 24 ++++++++++--------- .../ui/auth/AuthenticationFragment.kt | 17 ++++++++----- .../mealient/ui/baseurl/BaseURLFragment.kt | 9 +++---- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/gq/kirmanak/mealient/extensions/ViewExtensions.kt b/app/src/main/java/gq/kirmanak/mealient/extensions/ViewExtensions.kt index afb1fad..37b65c9 100644 --- a/app/src/main/java/gq/kirmanak/mealient/extensions/ViewExtensions.kt +++ b/app/src/main/java/gq/kirmanak/mealient/extensions/ViewExtensions.kt @@ -7,9 +7,11 @@ import android.view.WindowInsets import android.widget.EditText import android.widget.TextView import androidx.annotation.RequiresApi +import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity import androidx.core.widget.doAfterTextChanged -import androidx.lifecycle.LifecycleCoroutineScope +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.lifecycleScope import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.google.android.material.textfield.TextInputLayout import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -21,6 +23,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch import timber.log.Timber @OptIn(ExperimentalCoroutinesApi::class) @@ -83,25 +86,24 @@ fun ChannelResult.logErrors(methodName: String): ChannelResult { fun EditText.checkIfInputIsEmpty( inputLayout: TextInputLayout, - lifecycleCoroutineScope: LifecycleCoroutineScope, - errorText: () -> String + lifecycleOwner: LifecycleOwner, + @StringRes stringId: Int, + trim: Boolean = true, ): String? { - Timber.v("checkIfInputIsEmpty() called with: input = $this, inputLayout = $inputLayout, errorText = $errorText") - val text = text?.toString() + val input = if (trim) text?.trim() else text + val text = input?.toString().orEmpty() Timber.d("Input text is \"$text\"") - if (text.isNullOrEmpty()) { - inputLayout.error = errorText() - lifecycleCoroutineScope.launchWhenResumed { + return text.ifEmpty { + inputLayout.error = resources.getString(stringId) + lifecycleOwner.lifecycleScope.launch { waitUntilNotEmpty() inputLayout.error = null } - return null + null } - return text } suspend fun EditText.waitUntilNotEmpty() { - Timber.v("waitUntilNotEmpty() called with: input = $this") textChangesFlow().filterNotNull().first { it.isNotEmpty() } Timber.v("waitUntilNotEmpty() returned") } \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/auth/AuthenticationFragment.kt b/app/src/main/java/gq/kirmanak/mealient/ui/auth/AuthenticationFragment.kt index ece0518..820ae22 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/auth/AuthenticationFragment.kt +++ b/app/src/main/java/gq/kirmanak/mealient/ui/auth/AuthenticationFragment.kt @@ -39,13 +39,18 @@ class AuthenticationFragment : Fragment(R.layout.fragment_authentication) { private fun onLoginClicked(): Unit = with(binding) { Timber.v("onLoginClicked() called") - val email: String = emailInput.checkIfInputIsEmpty(emailInputLayout, lifecycleScope) { - getString(R.string.fragment_authentication_email_input_empty) - } ?: return + val email: String = emailInput.checkIfInputIsEmpty( + inputLayout = emailInputLayout, + lifecycleOwner = viewLifecycleOwner, + stringId = R.string.fragment_authentication_email_input_empty, + ) ?: return - val pass: String = passwordInput.checkIfInputIsEmpty(passwordInputLayout, lifecycleScope) { - getString(R.string.fragment_authentication_password_input_empty) - } ?: return + val pass: String = passwordInput.checkIfInputIsEmpty( + inputLayout = passwordInputLayout, + lifecycleOwner = viewLifecycleOwner, + stringId = R.string.fragment_authentication_password_input_empty, + trim = false, + ) ?: return button.isClickable = false viewLifecycleOwner.lifecycleScope.launch { diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/baseurl/BaseURLFragment.kt b/app/src/main/java/gq/kirmanak/mealient/ui/baseurl/BaseURLFragment.kt index dc6ef5a..6c8abce 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/baseurl/BaseURLFragment.kt +++ b/app/src/main/java/gq/kirmanak/mealient/ui/baseurl/BaseURLFragment.kt @@ -4,7 +4,6 @@ import android.os.Bundle import android.view.View import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels -import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import by.kirich1409.viewbindingdelegate.viewBinding import dagger.hilt.android.AndroidEntryPoint @@ -29,9 +28,11 @@ class BaseURLFragment : Fragment(R.layout.fragment_base_url) { private fun onProceedClick(view: View) { Timber.v("onProceedClick() called with: view = $view") - val url = binding.urlInput.checkIfInputIsEmpty(binding.urlInputLayout, lifecycleScope) { - getString(R.string.fragment_baseurl_url_input_empty) - } ?: return + val url = binding.urlInput.checkIfInputIsEmpty( + inputLayout = binding.urlInputLayout, + lifecycleOwner = viewLifecycleOwner, + stringId = R.string.fragment_baseurl_url_input_empty, + ) ?: return viewModel.saveBaseUrl(url) } From 9d092805227dc731ab1475f5bcbbac40898d2889 Mon Sep 17 00:00:00 2001 From: Kirill Kamakin Date: Mon, 4 Apr 2022 21:20:30 +0500 Subject: [PATCH 2/2] Bump version to 0.1.6 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index e8f914c..bf37cce 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,8 +14,8 @@ android { applicationId "gq.kirmanak.mealient" minSdk 23 targetSdk 31 - versionCode 6 - versionName "0.1.5" + versionCode 7 + versionName "0.1.6" } signingConfigs {