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 { 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) }