From b78dc24870c2fd7aa572209294c95c1eae95fe58 Mon Sep 17 00:00:00 2001 From: null Date: Tue, 30 Jun 2026 21:24:36 -0500 Subject: [PATCH] feat(backup): add back button to restore screens (R24-d) --- .../closer/core/navigation/AppNavigation.kt | 5 +++-- .../app/closer/ui/pairing/RestoreScreens.kt | 20 ++++++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) 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 081fa85b..09657e82 100644 --- a/app/src/main/java/app/closer/core/navigation/AppNavigation.kt +++ b/app/src/main/java/app/closer/core/navigation/AppNavigation.kt @@ -401,11 +401,12 @@ fun AppNavigation( navController.navigate(AppRoute.HOME) { popUpTo(AppRoute.RESTORE_REQUEST) { inclusive = true } } - } + }, + onBack = navigateBackOrHome ) } composable(route = AppRoute.RESTORE_CONSENT) { - RestoreConsentScreen(onDone = { navController.popBackStack() }) + RestoreConsentScreen(onDone = { navController.popBackStack() }, onBack = navigateBackOrHome) } // Wheel / Category Selection diff --git a/app/src/main/java/app/closer/ui/pairing/RestoreScreens.kt b/app/src/main/java/app/closer/ui/pairing/RestoreScreens.kt index f3d52215..5766a3d9 100644 --- a/app/src/main/java/app/closer/ui/pairing/RestoreScreens.kt +++ b/app/src/main/java/app/closer/ui/pairing/RestoreScreens.kt @@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.foundation.layout.width @@ -22,6 +23,8 @@ import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Checkbox import androidx.compose.material3.CheckboxDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextFieldDefaults @@ -59,6 +62,7 @@ import app.closer.ui.settings.SettingsPrimaryDeep @Composable fun RestoreRequestScreen( onDone: () -> Unit, + onBack: () -> Unit = {}, viewModel: RestoreViewModel = hiltViewModel() ) { val state by viewModel.uiState.collectAsState() @@ -66,7 +70,7 @@ fun RestoreRequestScreen( LaunchedEffect(state.restoreComplete) { if (state.restoreComplete) onDone() } LaunchedEffect(state.error) { state.error?.let { snackbar.showSnackbar(it); viewModel.dismissError() } } - RestoreScaffold(snackbar, icon = CloserGlyphs.Couple, title = "Restore from your partner") { + RestoreScaffold(snackbar, icon = CloserGlyphs.Couple, title = "Restore from your partner", onBack = onBack) { val code = state.verificationCode if (code == null) { Text( @@ -97,6 +101,7 @@ fun RestoreRequestScreen( @Composable fun RestoreConsentScreen( onDone: () -> Unit, + onBack: () -> Unit = {}, viewModel: RestoreViewModel = hiltViewModel() ) { val state by viewModel.uiState.collectAsState() @@ -105,7 +110,7 @@ fun RestoreConsentScreen( LaunchedEffect(state.consentComplete) { if (state.consentComplete) onDone() } LaunchedEffect(state.error) { state.error?.let { snackbar.showSnackbar(it); viewModel.dismissError() } } - RestoreScaffold(snackbar, icon = CloserGlyphs.Lock, title = "Help your partner restore") { + RestoreScaffold(snackbar, icon = CloserGlyphs.Lock, title = "Help your partner restore", onBack = onBack) { when { // Wait for the first observation before deciding what to show (avoids flashing "no request"). !state.consentChecked -> { @@ -222,6 +227,7 @@ private fun RestoreScaffold( snackbar: SnackbarHostState, icon: androidx.compose.ui.graphics.vector.ImageVector, title: String, + onBack: (() -> Unit)? = null, content: @Composable () -> Unit ) { Scaffold( @@ -240,7 +246,15 @@ private fun RestoreScaffold( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Top ) { - Spacer(Modifier.height(48.dp)) + // Back affordance — important when reached from Settings → "Help my partner restore". + Row(modifier = Modifier.fillMaxWidth().height(48.dp), verticalAlignment = Alignment.CenterVertically) { + if (onBack != null) { + IconButton(onClick = onBack, modifier = Modifier.offset(x = (-12).dp)) { + Icon(CloserGlyphs.Back, contentDescription = "Back", tint = SettingsInk) + } + } + } + Spacer(Modifier.height(8.dp)) StatusGlyph(icon = icon, tint = SettingsPrimaryDeep, container = SettingsPrimary.copy(alpha = 0.12f)) Spacer(Modifier.height(20.dp)) Text(title, style = MaterialTheme.typography.headlineSmall, color = SettingsInk,