From ebd3b2ed1f0c7c7b20987ef996e7770e997d18c0 Mon Sep 17 00:00:00 2001 From: null Date: Thu, 25 Jun 2026 09:37:36 -0500 Subject: [PATCH] fix(nav): clear onboarding/auth back stack on entry->Home (C-NAV-001 P1) Navigating to Home from any entry route (onboarding/profile/pair/login/signup/forgot) now resets the stack (popUpTo(0) inclusive) so Home is the back-stack root. Previously the graph start (ONBOARDING) lingered under Home, so system Back from Home walked backward into the onboarding carousel -> welcome/login, making a signed-in user look logged out. Verified: Back from Home now exits the app to the launcher. Co-Authored-By: Claude Opus 4.8 --- .../closer/core/navigation/AppNavigation.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/src/main/java/app/closer/core/navigation/AppNavigation.kt b/app/src/main/java/app/closer/core/navigation/AppNavigation.kt index fd8d1f7f..0a86fed2 100644 --- a/app/src/main/java/app/closer/core/navigation/AppNavigation.kt +++ b/app/src/main/java/app/closer/core/navigation/AppNavigation.kt @@ -124,9 +124,29 @@ fun AppNavigation( selectTab(AppRoute.HOME) } } + // The pre-app entry flow (onboarding + profile/pairing setup + auth). Leaving any of + // these for Home must CLEAR them from the back stack — otherwise the graph start + // (ONBOARDING) lingers as the root under Home and a system Back from Home walks + // backward into the onboarding carousel / login screen, making a signed-in user look + // logged out (C-NAV-001). + val entryRoutes = setOf( + AppRoute.ONBOARDING, + AppRoute.CREATE_PROFILE, + AppRoute.PAIR_PROMPT, + AppRoute.LOGIN, + AppRoute.SIGN_UP, + AppRoute.FORGOT_PASSWORD + ) val navigateRoute: (String) -> Unit = { route -> when { route == "back" -> navigateBackOrHome() + // Completing onboarding/auth: make Home the back-stack root (wipe the entire + // entry flow) so Back from Home exits the app, never resurfaces onboarding/login. + route == AppRoute.HOME && currentRoute in entryRoutes -> + navController.navigate(AppRoute.HOME) { + popUpTo(0) { inclusive = true } + launchSingleTop = true + } // Top-level tabs must use tab-switch semantics. Plain-navigating to a // tab (e.g. a "Game waiting" card → PLAY) would stack it on the current // tab; the bottom bar then saves that substack and `restoreState` later