diff --git a/app/src/main/java/com/hawhamburg/micr0bu/ui/navigation/AppNavigation.kt b/app/src/main/java/com/hawhamburg/micr0bu/ui/navigation/AppNavigation.kt index 8b0763f..e7cf0f4 100644 --- a/app/src/main/java/com/hawhamburg/micr0bu/ui/navigation/AppNavigation.kt +++ b/app/src/main/java/com/hawhamburg/micr0bu/ui/navigation/AppNavigation.kt @@ -63,6 +63,23 @@ private val bottomNavItems = listOf( Screen.Settings, ) +/** + * True if [route] is this tab's own screen or one of its sub-screens. + * + * The graph is flat, so ownership is derived from the route naming convention: every Settings + * sub-screen is "settings/...", and a trip review is "trip_review/{tripId}" belonging to Trips. + * Without this, a tab stops looking selected the moment you open anything inside it. + */ +private fun Screen.ownsRoute(route: String?): Boolean { + if (route == null) return false + if (route == this.route) return true + return when (this) { + Screen.Settings -> route.startsWith("settings/") + Screen.TripHistory -> route.startsWith("trip_review") + else -> false + } +} + @Composable fun BottomNavBar(navController: NavController) { val backStackEntry by navController.currentBackStackEntryAsState() @@ -70,13 +87,24 @@ fun BottomNavBar(navController: NavController) { NavigationBar { bottomNavItems.forEach { screen -> + val onThisTab = screen.ownsRoute(currentRoute) NavigationBarItem( - selected = currentRoute == screen.route, + selected = onThisTab, onClick = { - navController.navigate(screen.route) { - popUpTo(Screen.Dashboard.route) { saveState = true } - launchSingleTop = true - restoreState = true + if (onThisTab && currentRoute != screen.route) { + // Already inside this tab, just deeper in: pop back to the tab's own + // screen. Navigating instead would restoreState the saved back stack and + // land straight back on the sub-screen, which reads as the tap doing + // nothing - the reason Settings > Connection could not be left by tapping + // Settings. Leaves the rest of the stack intact, so Back still works + // exactly as before. + navController.popBackStack(screen.route, inclusive = false) + } else { + navController.navigate(screen.route) { + popUpTo(Screen.Dashboard.route) { saveState = true } + launchSingleTop = true + restoreState = true + } } }, icon = {