Show auth errors to the user

This commit is contained in:
Kirill Kamakin
2021-11-21 17:29:44 +03:00
parent 808e1ce359
commit d36ebfe50c
4 changed files with 58 additions and 32 deletions

View File

@@ -8,10 +8,11 @@ import android.widget.EditText
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import gq.kirmanak.mealient.R
import gq.kirmanak.mealient.data.auth.impl.AuthenticationError.*
import gq.kirmanak.mealient.databinding.FragmentAuthenticationBinding import gq.kirmanak.mealient.databinding.FragmentAuthenticationBinding
import timber.log.Timber import timber.log.Timber
@@ -59,30 +60,35 @@ class AuthenticationFragment : Fragment() {
findNavController().navigate(AuthenticationFragmentDirections.actionAuthenticationFragmentToRecipesFragment()) findNavController().navigate(AuthenticationFragmentDirections.actionAuthenticationFragmentToRecipesFragment())
} }
private fun onLoginClicked() { private fun onLoginClicked(): Unit = with(binding) {
Timber.v("onLoginClicked() called") Timber.v("onLoginClicked() called")
val email: String
val pass: String val email: String = checkIfInputIsEmpty(emailInput, emailInputLayout) {
val url: String getString(R.string.fragment_authentication_email_input_empty)
with(binding) {
email = checkIfInputIsEmpty(emailInput, emailInputLayout) {
"Email is empty"
} ?: return } ?: return
pass = checkIfInputIsEmpty(passwordInput, passwordInputLayout) {
"Pass is empty" val pass: String = checkIfInputIsEmpty(passwordInput, passwordInputLayout) {
getString(R.string.fragment_authentication_password_input_empty)
} ?: return } ?: return
url = checkIfInputIsEmpty(urlInput, urlInputLayout) {
"URL is empty" val url: String = checkIfInputIsEmpty(urlInput, urlInputLayout) {
getString(R.string.fragment_authentication_url_input_empty)
} ?: return } ?: return
button.isClickable = false
viewModel.authenticate(email, pass, url).observe(viewLifecycleOwner) {
Timber.d("onLoginClicked: result $it")
passwordInputLayout.error = when (it.exceptionOrNull()) {
is Unauthorized -> getString(R.string.fragment_authentication_credentials_incorrect)
else -> null
} }
binding.button.isClickable = false urlInputLayout.error = when (it.exceptionOrNull()) {
viewLifecycleOwner.lifecycleScope.launchWhenResumed { is NoServerConnection -> getString(R.string.fragment_authentication_no_connection)
runCatching { is NotMealie -> getString(R.string.fragment_authentication_unexpected_response)
viewModel.authenticate(email, pass, url) is Unauthorized, null -> null
}.onFailure { else -> getString(R.string.fragment_authentication_unknown_error)
Timber.e(it, "Can't authenticate")
} }
binding.button.isClickable = true button.isClickable = true
} }
} }

View File

@@ -1,9 +1,6 @@
package gq.kirmanak.mealient.ui.auth package gq.kirmanak.mealient.ui.auth
import androidx.lifecycle.LiveData import androidx.lifecycle.*
import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import gq.kirmanak.mealient.data.auth.AuthRepo import gq.kirmanak.mealient.data.auth.AuthRepo
import gq.kirmanak.mealient.data.recipes.RecipeRepo import gq.kirmanak.mealient.data.recipes.RecipeRepo
@@ -16,13 +13,22 @@ class AuthenticationViewModel @Inject constructor(
private val authRepo: AuthRepo, private val authRepo: AuthRepo,
private val recipeRepo: RecipeRepo private val recipeRepo: RecipeRepo
) : ViewModel() { ) : ViewModel() {
init {
Timber.v("constructor called")
}
suspend fun authenticate(username: String, password: String, baseUrl: String) { fun authenticate(username: String, password: String, baseUrl: String): LiveData<Result<Unit>> {
Timber.v("authenticate() called with: username = $username, password = $password, baseUrl = $baseUrl") Timber.v("authenticate() called with: username = $username, password = $password, baseUrl = $baseUrl")
val result = MutableLiveData<Result<Unit>>()
viewModelScope.launch {
runCatching {
authRepo.authenticate(username, password, baseUrl) authRepo.authenticate(username, password, baseUrl)
}.onFailure {
Timber.e(it, "authenticate: can't authenticate")
result.value = Result.failure(it)
}.onSuccess {
Timber.d("authenticate: authenticated")
result.value = Result.success(Unit)
}
}
return result
} }
fun authenticationStatuses(): LiveData<Boolean> { fun authenticationStatuses(): LiveData<Boolean> {

View File

@@ -14,4 +14,11 @@
<string name="fragment_disclaimer_button_okay">Хорошо</string> <string name="fragment_disclaimer_button_okay">Хорошо</string>
<string name="fragment_disclaimer_header">ДИСКЛЕЙМЕР</string> <string name="fragment_disclaimer_header">ДИСКЛЕЙМЕР</string>
<string name="fragment_disclaimer_main_text">Этот проект разрабатывается независимо от основного проекта Meale. Он не связан с разработчиками Mealie. О любых проблемах следует писать в репозиторий Mealient, НЕ в репозиторий Mealie.</string> <string name="fragment_disclaimer_main_text">Этот проект разрабатывается независимо от основного проекта Meale. Он не связан с разработчиками Mealie. О любых проблемах следует писать в репозиторий Mealient, НЕ в репозиторий Mealie.</string>
<string name="fragment_authentication_email_input_empty">E-mail не может быть пустым</string>
<string name="fragment_authentication_password_input_empty">Пароль не может быть пустым</string>
<string name="fragment_authentication_url_input_empty">URL не может быть пустым</string>
<string name="fragment_authentication_credentials_incorrect">E-mail или пароль не подходит.</string>
<string name="fragment_authentication_no_connection">Ошибка подключения, проверьте адрес.</string>
<string name="fragment_authentication_unexpected_response">Неожиданный ответ. Это Mealie?</string>
<string name="fragment_authentication_unknown_error">Что-то пошло не так, попробуйте еще раз.</string>
</resources> </resources>

View File

@@ -16,4 +16,11 @@
<string name="fragment_disclaimer_header">DISCLAIMER</string> <string name="fragment_disclaimer_header">DISCLAIMER</string>
<string name="fragment_disclaimer_button_okay">Okay</string> <string name="fragment_disclaimer_button_okay">Okay</string>
<string name="view_holder_recipe_instructions_step">Step: %d</string> <string name="view_holder_recipe_instructions_step">Step: %d</string>
<string name="fragment_authentication_email_input_empty">E-mail can\'t be empty</string>
<string name="fragment_authentication_password_input_empty">Password can\'t be empty</string>
<string name="fragment_authentication_url_input_empty">URL can\'t be empty</string>
<string name="fragment_authentication_credentials_incorrect">E-mail or password is incorrect.</string>
<string name="fragment_authentication_no_connection">Can\'t connect, check address.</string>
<string name="fragment_authentication_unexpected_response">Unexpected response. Is it Mealie?</string>
<string name="fragment_authentication_unknown_error">Something went wrong, please try again.</string>
</resources> </resources>