From 403e1e6c18748e8e5ebd822131c812401b0596ae Mon Sep 17 00:00:00 2001 From: Jay Ohms Date: Sat, 24 Feb 2024 16:22:01 -0500 Subject: [PATCH] Stop using NavigationUI.setupWithNavController() for toolbar setup. It's visually buggy and doesn't allow the back button to display unless the start destination is a unique fragment from other destinations. --- .../features/imageviewer/ImageViewerFragment.kt | 2 +- .../turbo/demo/features/web/WebModalFragment.kt | 14 +------------- .../dev/hotwire/turbo/demo/util/Extensions.kt | 4 ---- .../turbo/delegates/TurboFragmentDelegate.kt | 11 ++++++++++- .../dev/hotwire/turbo/nav/TurboNavDestination.kt | 7 +++++++ .../kotlin/dev/hotwire/turbo/nav/TurboNavigator.kt | 8 ++++---- .../dev/hotwire/turbo/util/TurboExtensions.kt | 12 ++++++++++++ turbo/src/main/res/drawable/ic_back.xml | 9 +++++++++ turbo/src/main/res/drawable/ic_close.xml | 9 +++++++++ 9 files changed, 53 insertions(+), 23 deletions(-) create mode 100644 turbo/src/main/res/drawable/ic_back.xml create mode 100644 turbo/src/main/res/drawable/ic_close.xml diff --git a/demo/src/main/kotlin/dev/hotwire/turbo/demo/features/imageviewer/ImageViewerFragment.kt b/demo/src/main/kotlin/dev/hotwire/turbo/demo/features/imageviewer/ImageViewerFragment.kt index d1ba8602..78f09b66 100644 --- a/demo/src/main/kotlin/dev/hotwire/turbo/demo/features/imageviewer/ImageViewerFragment.kt +++ b/demo/src/main/kotlin/dev/hotwire/turbo/demo/features/imageviewer/ImageViewerFragment.kt @@ -10,7 +10,7 @@ import dev.hotwire.turbo.demo.R import dev.hotwire.turbo.fragments.TurboFragment import dev.hotwire.turbo.nav.TurboNavGraphDestination import com.bumptech.glide.Glide -import dev.hotwire.turbo.demo.util.displayBackButtonAsCloseIcon +import dev.hotwire.turbo.util.displayBackButtonAsCloseIcon @TurboNavGraphDestination(uri = "turbo://fragment/image_viewer") class ImageViewerFragment : TurboFragment(), NavDestination { diff --git a/demo/src/main/kotlin/dev/hotwire/turbo/demo/features/web/WebModalFragment.kt b/demo/src/main/kotlin/dev/hotwire/turbo/demo/features/web/WebModalFragment.kt index 4a3d5397..36212cc8 100644 --- a/demo/src/main/kotlin/dev/hotwire/turbo/demo/features/web/WebModalFragment.kt +++ b/demo/src/main/kotlin/dev/hotwire/turbo/demo/features/web/WebModalFragment.kt @@ -1,18 +1,6 @@ package dev.hotwire.turbo.demo.features.web -import android.os.Bundle -import android.view.View -import dev.hotwire.turbo.demo.util.displayBackButtonAsCloseIcon import dev.hotwire.turbo.nav.TurboNavGraphDestination @TurboNavGraphDestination(uri = "turbo://fragment/web/modal") -class WebModalFragment : WebFragment() { - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - initToolbar() - } - - private fun initToolbar() { - toolbarForNavigation()?.displayBackButtonAsCloseIcon() - } -} +class WebModalFragment : WebFragment() diff --git a/demo/src/main/kotlin/dev/hotwire/turbo/demo/util/Extensions.kt b/demo/src/main/kotlin/dev/hotwire/turbo/demo/util/Extensions.kt index 7cfa592e..8ba4a804 100644 --- a/demo/src/main/kotlin/dev/hotwire/turbo/demo/util/Extensions.kt +++ b/demo/src/main/kotlin/dev/hotwire/turbo/demo/util/Extensions.kt @@ -17,10 +17,6 @@ import dev.hotwire.turbo.demo.strada.bridgeComponentFactories val TurboPathConfigurationProperties.description: String? get() = get("description") -fun Toolbar.displayBackButtonAsCloseIcon() { - navigationIcon = ContextCompat.getDrawable(context, R.drawable.ic_close) -} - @Suppress("DEPRECATION") fun WebView.initDayNightTheme() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { diff --git a/turbo/src/main/kotlin/dev/hotwire/turbo/delegates/TurboFragmentDelegate.kt b/turbo/src/main/kotlin/dev/hotwire/turbo/delegates/TurboFragmentDelegate.kt index 13bf24e4..c4a0dde6 100644 --- a/turbo/src/main/kotlin/dev/hotwire/turbo/delegates/TurboFragmentDelegate.kt +++ b/turbo/src/main/kotlin/dev/hotwire/turbo/delegates/TurboFragmentDelegate.kt @@ -8,6 +8,8 @@ import dev.hotwire.turbo.nav.TurboNavDestination import dev.hotwire.turbo.nav.TurboNavigator import dev.hotwire.turbo.session.TurboSessionModalResult import dev.hotwire.turbo.session.TurboSessionViewModel +import dev.hotwire.turbo.util.displayBackButton +import dev.hotwire.turbo.util.displayBackButtonAsCloseIcon import dev.hotwire.turbo.util.logEvent /** @@ -95,7 +97,14 @@ class TurboFragmentDelegate(private val navDestination: TurboNavDestination) { private fun initToolbar() { navDestination.toolbarForNavigation()?.let { - NavigationUI.setupWithNavController(it, fragment.findNavController()) + if (!navigator.isAtStartDestination()) { + if (navDestination.isModal) { + it.displayBackButtonAsCloseIcon() + } else { + it.displayBackButton() + } + } + it.setNavigationOnClickListener { navDestination.navigateUp() } diff --git a/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavDestination.kt b/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavDestination.kt index 30eb5b99..385cb1cf 100644 --- a/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavDestination.kt +++ b/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavDestination.kt @@ -15,6 +15,7 @@ import androidx.navigation.navOptions import androidx.navigation.ui.R import dev.hotwire.turbo.config.TurboPathConfiguration import dev.hotwire.turbo.config.TurboPathConfigurationProperties +import dev.hotwire.turbo.config.context import dev.hotwire.turbo.delegates.TurboFragmentDelegate import dev.hotwire.turbo.delegates.TurboNestedFragmentDelegate import dev.hotwire.turbo.fragments.TurboFragment @@ -81,6 +82,12 @@ interface TurboNavDestination { val isActive: Boolean get() = fragment.isAdded && !fragment.isDetached + /** + * Specifies whether the destination was presented in a modal context. + */ + val isModal: Boolean + get() = pathProperties.context == TurboNavPresentationContext.MODAL + /** * Gets the delegate instance that handles the Fragment's lifecycle events. */ diff --git a/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavigator.kt b/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavigator.kt index 9885172d..d3dbd3a1 100644 --- a/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavigator.kt +++ b/turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavigator.kt @@ -20,6 +20,10 @@ internal class TurboNavigator(private val navDestination: TurboNavDestination) { onReady() } + fun isAtStartDestination(): Boolean { + return currentController().previousBackStackEntry == null + } + fun navigateUp() { onNavigationVisit { if (fragment is DialogFragment) { @@ -267,10 +271,6 @@ internal class TurboNavigator(private val navDestination: TurboNavDestination) { return navDestination.navHostForNavigation(location).navController } - private fun isAtStartDestination(): Boolean { - return currentController().previousBackStackEntry == null - } - private fun shouldNavigate(location: String): Boolean { val shouldNavigate = navDestination.shouldNavigateTo(location) diff --git a/turbo/src/main/kotlin/dev/hotwire/turbo/util/TurboExtensions.kt b/turbo/src/main/kotlin/dev/hotwire/turbo/util/TurboExtensions.kt index b570d46b..4fe5f4e6 100644 --- a/turbo/src/main/kotlin/dev/hotwire/turbo/util/TurboExtensions.kt +++ b/turbo/src/main/kotlin/dev/hotwire/turbo/util/TurboExtensions.kt @@ -5,14 +5,26 @@ import android.animation.ValueAnimator import android.content.Context import android.os.Handler import android.webkit.WebResourceRequest +import androidx.appcompat.widget.Toolbar +import androidx.core.content.ContextCompat import androidx.navigation.NavBackStackEntry import com.google.gson.Gson import com.google.gson.GsonBuilder import com.google.gson.reflect.TypeToken +import dev.hotwire.turbo.R import dev.hotwire.turbo.visit.TurboVisitAction import dev.hotwire.turbo.visit.TurboVisitActionAdapter import java.io.File +fun Toolbar.displayBackButton() { + navigationIcon = ContextCompat.getDrawable(context, R.drawable.ic_back) +} + +fun Toolbar.displayBackButtonAsCloseIcon() { + navigationIcon = ContextCompat.getDrawable(context, R.drawable.ic_close) +} + + internal fun Context.runOnUiThread(func: () -> Unit) { when (mainLooper.isCurrentThread) { true -> func() diff --git a/turbo/src/main/res/drawable/ic_back.xml b/turbo/src/main/res/drawable/ic_back.xml new file mode 100644 index 00000000..ba6cb699 --- /dev/null +++ b/turbo/src/main/res/drawable/ic_back.xml @@ -0,0 +1,9 @@ + + + diff --git a/turbo/src/main/res/drawable/ic_close.xml b/turbo/src/main/res/drawable/ic_close.xml new file mode 100644 index 00000000..954d81ef --- /dev/null +++ b/turbo/src/main/res/drawable/ic_close.xml @@ -0,0 +1,9 @@ + + +