diff --git a/composeApp/src/commonMain/kotlin/ru/fromchat/ui/NavControllerExtensions.kt b/composeApp/src/commonMain/kotlin/ru/fromchat/ui/NavControllerExtensions.kt deleted file mode 100644 index c9dcce7..0000000 --- a/composeApp/src/commonMain/kotlin/ru/fromchat/ui/NavControllerExtensions.kt +++ /dev/null @@ -1,19 +0,0 @@ -package ru.fromchat.ui - -import androidx.navigation.NavController - -/** - * Clears the entire back stack except the current screen - */ -fun NavController.wipeBackStack() { - // Keep popping until there are no previous entries - var entry = previousBackStackEntry - while (entry != null) { - val destinationId = entry.destination.id - val success = popBackStack(destinationId, inclusive = true) - if (!success) break - // Check again after popping - entry = previousBackStackEntry - } -} - diff --git a/composeApp/src/commonMain/kotlin/ru/fromchat/ui/setup/ServerConfigScreen.kt b/composeApp/src/commonMain/kotlin/ru/fromchat/ui/setup/ServerConfigScreen.kt index 5ea1dbc..f24ef9c 100644 --- a/composeApp/src/commonMain/kotlin/ru/fromchat/ui/setup/ServerConfigScreen.kt +++ b/composeApp/src/commonMain/kotlin/ru/fromchat/ui/setup/ServerConfigScreen.kt @@ -39,6 +39,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.unit.dp +import com.pr0gramm3r101.utils.navigateAndWipeBackStack import com.pr0gramm3r101.utils.storage.ServerConfigData import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource @@ -54,7 +55,6 @@ import ru.fromchat.server_config_title import ru.fromchat.server_url_hint import ru.fromchat.server_url_label import ru.fromchat.ui.LocalNavController -import ru.fromchat.ui.wipeBackStack @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -166,11 +166,8 @@ fun ServerConfigScreen() { // Shutdown WebSocket (will reconnect on login) WebSocketManager.shutdown() - // Clear entire back stack except current screen - navController.wipeBackStack() - - // Navigate to login - navController.navigate("login") + // Navigate to login and wipe entire back stack + navController.navigateAndWipeBackStack("login") } }, enabled = !isLoading && serverUrl.isNotBlank(), diff --git a/utils/build.gradle.kts b/utils/build.gradle.kts index c9cd332..f2e92af 100644 --- a/utils/build.gradle.kts +++ b/utils/build.gradle.kts @@ -37,6 +37,7 @@ kotlin { implementation(libs.constraintlayout) implementation(compose.materialIconsExtended) implementation(libs.jetbrains.kotlinx.coroutines.core) + implementation(libs.navigation.compose) } androidMain.dependencies { diff --git a/utils/src/commonMain/kotlin/com/pr0gramm3r101/utils/Compose.kt b/utils/src/commonMain/kotlin/com/pr0gramm3r101/utils/Compose.kt new file mode 100644 index 0000000..2d44c1e --- /dev/null +++ b/utils/src/commonMain/kotlin/com/pr0gramm3r101/utils/Compose.kt @@ -0,0 +1,38 @@ +package com.pr0gramm3r101.utils + +import androidx.navigation.NavController + +/** + * Navigates to the specified route and clears the entire back stack. + * This ensures the destination becomes the new root of the navigation stack. + * + * @param route The destination route to navigate to + * @param launchSingleTop If true, prevents multiple instances of the same destination + */ +fun NavController.navigateAndWipeBackStack(route: String, launchSingleTop: Boolean = true) { + // First, pop all previous entries (keeping current screen for now) + while (previousBackStackEntry != null) { + if (!popBackStack()) { + break + } + } + + // Get current route to pop it with the navigation + val currentRoute = currentBackStackEntry?.destination?.route + + // Navigate to the new route, removing the current screen as well + if (currentRoute != null && currentRoute != route) { + navigate(route) { + popUpTo(currentRoute) { + inclusive = true + } + this.launchSingleTop = launchSingleTop + } + } else { + // Fallback: just navigate if current route is same or null + navigate(route) { + this.launchSingleTop = launchSingleTop + } + } +} +