diff --git a/app/src/main/java/com/m57/hermescontrol/Navigation.kt b/app/src/main/java/com/m57/hermescontrol/Navigation.kt index f380942f..25848b12 100644 --- a/app/src/main/java/com/m57/hermescontrol/Navigation.kt +++ b/app/src/main/java/com/m57/hermescontrol/Navigation.kt @@ -66,12 +66,13 @@ private fun appEntryProvider( openDrawer: () -> Unit, ) = entryProvider { entry { + // B7 (Jun 30 2026, kanban t_424): route landing screen buttons through navigateTo to prevent duplicate screens LandingScreenContent( onAuthLogin = { - NavigationController.backStack?.add(AuthLoginScreen) + NavigationController.navigateTo(AuthLoginScreen) }, onPairingLogin = { - NavigationController.backStack?.add(PairingCodeEntryScreen) + NavigationController.navigateTo(PairingCodeEntryScreen) }, ) } @@ -134,6 +135,13 @@ fun MainNavigation(sessionId: String? = null) { val gesturesEnabled = currentScreen in DRAWER_GESTURE_SCREENS val openDrawer: () -> Unit = { scope.launch { drawerState.open() } } + // B7 (Jun 30 2026, kanban t_424): close drawer if gestures are disabled to dismiss scrim + LaunchedEffect(gesturesEnabled) { + if (!gesturesEnabled && drawerState.isOpen) { + drawerState.snapTo(DrawerValue.Closed) + } + } + ModalNavigationDrawer( drawerState = drawerState, gesturesEnabled = gesturesEnabled, diff --git a/app/src/main/java/com/m57/hermescontrol/ui/authlogin/AuthLoginScreen.kt b/app/src/main/java/com/m57/hermescontrol/ui/authlogin/AuthLoginScreen.kt index 695bbe51..dded5df7 100644 --- a/app/src/main/java/com/m57/hermescontrol/ui/authlogin/AuthLoginScreen.kt +++ b/app/src/main/java/com/m57/hermescontrol/ui/authlogin/AuthLoginScreen.kt @@ -29,6 +29,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -69,6 +70,13 @@ fun AuthLoginScreen( } } + // Clear ephemeral connection state when screen leaves composition + // (ViewModel is Activity-scoped so it survives navigation — without + // this, stale connectionSuccess would auto-bounce the user on re-entry) + DisposableEffect(Unit) { + onDispose { viewModel.clearConnectionState() } + } + var passwordVisible by remember { mutableStateOf(false) } Box( diff --git a/app/src/main/java/com/m57/hermescontrol/ui/authlogin/AuthLoginViewModel.kt b/app/src/main/java/com/m57/hermescontrol/ui/authlogin/AuthLoginViewModel.kt index 028f5e34..e03ad361 100644 --- a/app/src/main/java/com/m57/hermescontrol/ui/authlogin/AuthLoginViewModel.kt +++ b/app/src/main/java/com/m57/hermescontrol/ui/authlogin/AuthLoginViewModel.kt @@ -9,6 +9,7 @@ import com.m57.hermescontrol.R import com.m57.hermescontrol.data.local.AuthManager import com.m57.hermescontrol.data.remote.ApiClient import com.m57.hermescontrol.data.remote.safeApiCall +import com.m57.hermescontrol.data.ws.HermesWsClient import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -65,6 +66,11 @@ class AuthLoginViewModel( _uiState.update { it.copy(host = value.trim(), errorMessage = null, authMode = null) } } + /** Reset ephemeral connection state (called when screen leaves composition). */ + fun clearConnectionState() { + _uiState.update { it.copy(connectionSuccess = false, errorMessage = null, isLoading = false) } + } + fun onPortChange(value: String) { _uiState.update { it.copy( @@ -271,6 +277,7 @@ class AuthLoginViewModel( AuthManager.setWsAuthParam("token") } ApiClient.rebuild() + HermesWsClient.connect() _uiState.update { it.copy(isLoading = false, connectionSuccess = true) } } } diff --git a/app/src/main/java/com/m57/hermescontrol/ui/settings/SettingsViewModel.kt b/app/src/main/java/com/m57/hermescontrol/ui/settings/SettingsViewModel.kt index 8e8b4570..baadca5a 100644 --- a/app/src/main/java/com/m57/hermescontrol/ui/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/m57/hermescontrol/ui/settings/SettingsViewModel.kt @@ -7,6 +7,7 @@ import com.m57.hermescontrol.data.local.AuthManager import com.m57.hermescontrol.data.remote.ApiClient import com.m57.hermescontrol.data.remote.NetworkResult import com.m57.hermescontrol.data.remote.safeApiCall +import com.m57.hermescontrol.data.ws.HermesWsClient import com.m57.hermescontrol.theme.BottomNavDisplayMode import com.m57.hermescontrol.theme.ThemePreference import com.m57.hermescontrol.theme.ThemePreset @@ -299,6 +300,7 @@ class SettingsViewModel( AuthManager.setToken(null) AuthManager.setSessionCookie(null) AuthManager.setWsAuthParam("token") + HermesWsClient.disconnect() // Don't rebuild ApiClient here — let the navigation complete first }