diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/BouncingIntentNav.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/BouncingIntentNav.kt index d441417a4..a345ed112 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/BouncingIntentNav.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/BouncingIntentNav.kt @@ -25,6 +25,7 @@ import android.content.Intent import android.net.Uri import androidx.compose.material3.DrawerState import androidx.compose.material3.DrawerValue +import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import com.vitorpamplona.amethyst.ui.MainActivity import com.vitorpamplona.amethyst.ui.navigation.routes.Route @@ -98,6 +99,7 @@ class BouncingIntentNav( override fun navBottomBar(route: Route) = nav(route) + @Composable override fun canPop(): Boolean = false override fun popBack() { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/EmptyNav.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/EmptyNav.kt index 06c7edab7..94c3f86a8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/EmptyNav.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/EmptyNav.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.navigation.navs import androidx.compose.material3.DrawerState import androidx.compose.material3.DrawerValue +import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import com.vitorpamplona.amethyst.ui.navigation.routes.Route import kotlinx.coroutines.CoroutineScope @@ -46,6 +47,7 @@ class EmptyNav : INav { override fun navBottomBar(route: Route) {} + @Composable override fun canPop(): Boolean = false override fun popBack() {} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/INav.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/INav.kt index 7ec762f8e..f7ceff737 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/INav.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/INav.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.amethyst.ui.navigation.navs import androidx.compose.material3.DrawerState +import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import com.vitorpamplona.amethyst.ui.navigation.routes.Route import kotlinx.coroutines.CoroutineScope @@ -43,6 +44,7 @@ interface INav { fun navBottomBar(route: Route) + @Composable fun canPop(): Boolean fun popBack() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/Nav.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/Nav.kt index 3d2a94b4f..05ca546fd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/Nav.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/Nav.kt @@ -23,8 +23,12 @@ package com.vitorpamplona.amethyst.ui.navigation.navs import android.annotation.SuppressLint import androidx.compose.material3.DrawerState import androidx.compose.material3.DrawerValue +import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable +import androidx.compose.runtime.getValue +import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavHostController +import androidx.navigation.compose.currentBackStackEntryAsState import com.vitorpamplona.amethyst.ui.navigation.BOTTOM_NAV_ROOT_KEY import com.vitorpamplona.amethyst.ui.navigation.isBottomNavRoot import com.vitorpamplona.amethyst.ui.navigation.routes.Route @@ -93,9 +97,20 @@ class Nav( } } + @Composable override fun canPop(): Boolean { - val current = controller.currentBackStackEntry ?: return false - if (current.isBottomNavRoot()) return false + // Observe the current entry as State so consumers recompose when the + // back stack settles after a navigation or back-swipe transition. + // A non-reactive read would leave a stale value behind: e.g. on + // back-swipe to Home, previousBackStackEntry is still the popping + // entry until the gesture finishes, and nothing would re-evaluate + // canPop afterwards. + val current by controller.currentBackStackEntryAsState() + val entry = current ?: return false + if (entry.isBottomNavRoot()) return false + // Home is the graph's start destination and nothing can sit below + // it, so a back arrow there is never meaningful. + if (entry.destination.id == controller.graph.findStartDestination().id) return false return controller.previousBackStackEntry != null }