From c98feceab476ef0ba014747ffa6cf86a8c7b626b Mon Sep 17 00:00:00 2001 From: Kirill Kamakin Date: Mon, 4 Apr 2022 18:54:48 +0500 Subject: [PATCH] Fix pressing back on AuthenticationFragment If login request isn't disabled when user presses back then they might get navigated back to authentication again. --- .../mealient/extensions/FragmentExtensions.kt | 30 +++++++++++++++++++ .../{ui => extensions}/ViewExtensions.kt | 2 +- .../ui/auth/AuthenticationFragment.kt | 4 ++- .../ui/auth/AuthenticationViewModel.kt | 15 ++++++++-- .../mealient/ui/baseurl/BaseURLFragment.kt | 2 +- .../mealient/ui/recipes/RecipesFragment.kt | 2 +- .../mealient/ui/splash/SplashFragment.kt | 4 +-- 7 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/gq/kirmanak/mealient/extensions/FragmentExtensions.kt rename app/src/main/java/gq/kirmanak/mealient/{ui => extensions}/ViewExtensions.kt (99%) diff --git a/app/src/main/java/gq/kirmanak/mealient/extensions/FragmentExtensions.kt b/app/src/main/java/gq/kirmanak/mealient/extensions/FragmentExtensions.kt new file mode 100644 index 0000000..511b2f3 --- /dev/null +++ b/app/src/main/java/gq/kirmanak/mealient/extensions/FragmentExtensions.kt @@ -0,0 +1,30 @@ +package gq.kirmanak.mealient.extensions + +import androidx.activity.OnBackPressedDispatcher +import androidx.activity.addCallback +import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch + +fun Fragment.executeOnceOnBackPressed(action: () -> Unit) { + val onBackPressedDispatcher = requireActivity().onBackPressedDispatcher + lifecycleScope.launch { + onBackPressedDispatcher.backPressedFlow().first() + action() + onBackPressedDispatcher.onBackPressed() // Execute other callbacks now + } +} + +@OptIn(ExperimentalCoroutinesApi::class) +fun OnBackPressedDispatcher.backPressedFlow(): Flow = callbackFlow { + val callback = addCallback { trySend(Unit) } + awaitClose { + callback.isEnabled = false + callback.remove() + } +} \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/ViewExtensions.kt b/app/src/main/java/gq/kirmanak/mealient/extensions/ViewExtensions.kt similarity index 99% rename from app/src/main/java/gq/kirmanak/mealient/ui/ViewExtensions.kt rename to app/src/main/java/gq/kirmanak/mealient/extensions/ViewExtensions.kt index 1b608d0..c123800 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/ViewExtensions.kt +++ b/app/src/main/java/gq/kirmanak/mealient/extensions/ViewExtensions.kt @@ -1,4 +1,4 @@ -package gq.kirmanak.mealient.ui +package gq.kirmanak.mealient.extensions import android.app.Activity import android.os.Build 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 0f68663..48d61f0 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 @@ -13,7 +13,8 @@ import dagger.hilt.android.AndroidEntryPoint import gq.kirmanak.mealient.R import gq.kirmanak.mealient.data.network.NetworkError.Unauthorized import gq.kirmanak.mealient.databinding.FragmentAuthenticationBinding -import gq.kirmanak.mealient.ui.checkIfInputIsEmpty +import gq.kirmanak.mealient.extensions.checkIfInputIsEmpty +import gq.kirmanak.mealient.extensions.executeOnceOnBackPressed import timber.log.Timber @AndroidEntryPoint @@ -28,6 +29,7 @@ class AuthenticationFragment : Fragment(R.layout.fragment_authentication) { super.onCreate(savedInstanceState) Timber.v("onCreate() called with: savedInstanceState = $savedInstanceState") authStatuses.observe(this, ::onAuthStatusChange) + executeOnceOnBackPressed { viewModel.disableLoginRequest() } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/auth/AuthenticationViewModel.kt b/app/src/main/java/gq/kirmanak/mealient/ui/auth/AuthenticationViewModel.kt index cfc3cf8..472078d 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/auth/AuthenticationViewModel.kt +++ b/app/src/main/java/gq/kirmanak/mealient/ui/auth/AuthenticationViewModel.kt @@ -45,8 +45,17 @@ class AuthenticationViewModel @Inject constructor( } } - fun login() { - Timber.v("login() called") - viewModelScope.launch { loginRequestsFlow.emit(true) } + fun enableLoginRequest() { + Timber.v("enableLoginRequest() called") + updateIsLoginRequested(true) + } + + fun disableLoginRequest() { + Timber.v("disableLoginRequest() called") + updateIsLoginRequested(false) + } + + private fun updateIsLoginRequested(isRequested: Boolean) { + viewModelScope.launch { loginRequestsFlow.emit(isRequested) } } } \ No newline at end of file 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 1a76b25..dc6ef5a 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 @@ -11,7 +11,7 @@ import dagger.hilt.android.AndroidEntryPoint import gq.kirmanak.mealient.R import gq.kirmanak.mealient.data.network.NetworkError import gq.kirmanak.mealient.databinding.FragmentBaseUrlBinding -import gq.kirmanak.mealient.ui.checkIfInputIsEmpty +import gq.kirmanak.mealient.extensions.checkIfInputIsEmpty import timber.log.Timber @AndroidEntryPoint 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 cf4b556..4e68417 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 @@ -13,9 +13,9 @@ import dagger.hilt.android.AndroidEntryPoint import gq.kirmanak.mealient.R import gq.kirmanak.mealient.data.recipes.db.entity.RecipeSummaryEntity import gq.kirmanak.mealient.databinding.FragmentRecipesBinding +import gq.kirmanak.mealient.extensions.refreshesLiveData import gq.kirmanak.mealient.ui.auth.AuthenticationState import gq.kirmanak.mealient.ui.auth.AuthenticationViewModel -import gq.kirmanak.mealient.ui.refreshesLiveData import kotlinx.coroutines.flow.collect import timber.log.Timber diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/splash/SplashFragment.kt b/app/src/main/java/gq/kirmanak/mealient/ui/splash/SplashFragment.kt index 32af21d..e52975f 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/splash/SplashFragment.kt +++ b/app/src/main/java/gq/kirmanak/mealient/ui/splash/SplashFragment.kt @@ -9,8 +9,8 @@ import androidx.navigation.NavDirections import androidx.navigation.fragment.findNavController import dagger.hilt.android.AndroidEntryPoint import gq.kirmanak.mealient.R -import gq.kirmanak.mealient.ui.setActionBarVisibility -import gq.kirmanak.mealient.ui.setSystemUiVisibility +import gq.kirmanak.mealient.extensions.setActionBarVisibility +import gq.kirmanak.mealient.extensions.setSystemUiVisibility import timber.log.Timber @AndroidEntryPoint