From a6e948ca6b405be1140114043092c805f70e5d53 Mon Sep 17 00:00:00 2001 From: Kirill Kamakin Date: Sat, 20 Nov 2021 22:07:43 +0300 Subject: [PATCH] Fix calling navigateToAuth twice and even more Calling that method several times in a row is not supported, Navigation library throws an Exception saying it doesn't know how to navigate there --- .../ui/auth/AuthenticationFragment.kt | 21 +++++++++------- .../mealient/ui/recipes/RecipesFragment.kt | 21 +++++++++------- .../ui/recipes/info/RecipeInfoFragment.kt | 25 +++++++++++-------- 3 files changed, 39 insertions(+), 28 deletions(-) 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 bfc8106..9df4261 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 @@ -7,6 +7,7 @@ import android.view.ViewGroup import android.widget.EditText import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels +import androidx.lifecycle.Observer import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import com.google.android.material.textfield.TextInputLayout @@ -21,18 +22,20 @@ class AuthenticationFragment : Fragment() { get() = checkNotNull(_binding) { "Binding requested when fragment is off screen" } private val viewModel by viewModels() + private val authStatuses by lazy { viewModel.authenticationStatuses() } + private val authStatusObserver = Observer { onAuthStatusChange(it) } + private fun onAuthStatusChange(isAuthenticated: Boolean) { + Timber.v("onAuthStatusChange() called with: isAuthenticated = $isAuthenticated") + if (isAuthenticated) { + authStatuses.removeObserver(authStatusObserver) + navigateToRecipes() + } + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Timber.v("onCreate() called with: savedInstanceState = $savedInstanceState") - listenToAuthenticationStatuses() - } - - private fun listenToAuthenticationStatuses() { - Timber.d("listenToAuthenticationStatuses() called") - viewModel.authenticationStatuses().observe(this) { - Timber.d("listenToAuthenticationStatuses: new status = $it") - if (it) navigateToRecipes() - } + authStatuses.observe(this, authStatusObserver) } override fun onCreateView( diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/RecipesFragment.kt b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/RecipesFragment.kt index d3c3757..e2d26d9 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/RecipesFragment.kt +++ b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/RecipesFragment.kt @@ -6,6 +6,7 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels +import androidx.lifecycle.Observer import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager @@ -25,7 +26,17 @@ class RecipesFragment : Fragment() { private val binding: FragmentRecipesBinding get() = checkNotNull(_binding) { "Binding requested when fragment is off screen" } private val viewModel by viewModels() + private val authViewModel by viewModels() + private val authStatuses by lazy { authViewModel.authenticationStatuses() } + private val authStatusObserver = Observer { onAuthStatusChange(it) } + private fun onAuthStatusChange(isAuthenticated: Boolean) { + Timber.v("onAuthStatusChange() called with: isAuthenticated = $isAuthenticated") + if (!isAuthenticated) { + authStatuses.removeObserver(authStatusObserver) + navigateToAuthFragment() + } + } override fun onCreateView( inflater: LayoutInflater, @@ -41,7 +52,7 @@ class RecipesFragment : Fragment() { super.onViewCreated(view, savedInstanceState) Timber.v("onViewCreated() called with: view = $view, savedInstanceState = $savedInstanceState") setupRecipeAdapter() - listenToAuthStatuses() + authStatuses.observe(this, authStatusObserver) } private fun navigateToRecipeInfo(recipeSummaryEntity: RecipeSummaryEntity) { @@ -54,14 +65,6 @@ class RecipesFragment : Fragment() { ) } - private fun listenToAuthStatuses() { - Timber.v("listenToAuthStatuses() called") - authViewModel.authenticationStatuses().observe(this) { - Timber.v("listenToAuthStatuses: new auth status = $it") - if (!it) navigateToAuthFragment() - } - } - private fun navigateToAuthFragment() { Timber.v("navigateToAuthFragment() called") findNavController().navigate(RecipesFragmentDirections.actionRecipesFragmentToAuthenticationFragment()) diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoFragment.kt b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoFragment.kt index 3bbefe1..bf5d700 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoFragment.kt +++ b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoFragment.kt @@ -6,6 +6,7 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels +import androidx.lifecycle.Observer import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs import androidx.recyclerview.widget.LinearLayoutManager @@ -19,10 +20,20 @@ class RecipeInfoFragment : Fragment() { private var _binding: FragmentRecipeInfoBinding? = null private val binding: FragmentRecipeInfoBinding get() = checkNotNull(_binding) { "Binding requested when fragment is off screen" } - private val authViewModel by viewModels() private val arguments by navArgs() private val viewModel by viewModels() + private val authViewModel by viewModels() + private val authStatuses by lazy { authViewModel.authenticationStatuses() } + private val authStatusObserver = Observer { onAuthStatusChange(it) } + private fun onAuthStatusChange(isAuthenticated: Boolean) { + Timber.v("onAuthStatusChange() called with: isAuthenticated = $isAuthenticated") + if (!isAuthenticated) { + authStatuses.removeObserver(authStatusObserver) + navigateToAuthFragment() + } + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -36,9 +47,11 @@ class RecipeInfoFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) Timber.v("onViewCreated() called with: view = $view, savedInstanceState = $savedInstanceState") - listenToAuthStatuses() + authStatuses.observe(this, authStatusObserver) + viewModel.loadRecipeImage(binding.image, arguments.recipeSlug) viewModel.loadRecipeInfo(arguments.recipeId, arguments.recipeSlug) + viewModel.recipeInfo.observe(viewLifecycleOwner) { Timber.d("onViewCreated: full info $it") binding.title.text = it.recipeSummaryEntity.name @@ -56,14 +69,6 @@ class RecipeInfoFragment : Fragment() { } } - private fun listenToAuthStatuses() { - Timber.v("listenToAuthStatuses() called") - authViewModel.authenticationStatuses().observe(this) { - Timber.d("listenToAuthStatuses: new auth status = $it") - if (!it) navigateToAuthFragment() - } - } - private fun navigateToAuthFragment() { Timber.v("navigateToAuthFragment() called") findNavController().navigate(RecipeInfoFragmentDirections.actionRecipeInfoFragmentToAuthenticationFragment())