feat(backup): add back button to restore screens (R24-d)

This commit is contained in:
null 2026-06-30 21:24:36 -05:00
parent 71227561e7
commit b78dc24870
2 changed files with 20 additions and 5 deletions

View File

@ -401,11 +401,12 @@ fun AppNavigation(
navController.navigate(AppRoute.HOME) { navController.navigate(AppRoute.HOME) {
popUpTo(AppRoute.RESTORE_REQUEST) { inclusive = true } popUpTo(AppRoute.RESTORE_REQUEST) { inclusive = true }
} }
} },
onBack = navigateBackOrHome
) )
} }
composable(route = AppRoute.RESTORE_CONSENT) { composable(route = AppRoute.RESTORE_CONSENT) {
RestoreConsentScreen(onDone = { navController.popBackStack() }) RestoreConsentScreen(onDone = { navController.popBackStack() }, onBack = navigateBackOrHome)
} }
// Wheel / Category Selection // Wheel / Category Selection

View File

@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
@ -22,6 +23,8 @@ import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Checkbox import androidx.compose.material3.Checkbox
import androidx.compose.material3.CheckboxDefaults import androidx.compose.material3.CheckboxDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.OutlinedTextFieldDefaults
@ -59,6 +62,7 @@ import app.closer.ui.settings.SettingsPrimaryDeep
@Composable @Composable
fun RestoreRequestScreen( fun RestoreRequestScreen(
onDone: () -> Unit, onDone: () -> Unit,
onBack: () -> Unit = {},
viewModel: RestoreViewModel = hiltViewModel() viewModel: RestoreViewModel = hiltViewModel()
) { ) {
val state by viewModel.uiState.collectAsState() val state by viewModel.uiState.collectAsState()
@ -66,7 +70,7 @@ fun RestoreRequestScreen(
LaunchedEffect(state.restoreComplete) { if (state.restoreComplete) onDone() } LaunchedEffect(state.restoreComplete) { if (state.restoreComplete) onDone() }
LaunchedEffect(state.error) { state.error?.let { snackbar.showSnackbar(it); viewModel.dismissError() } } 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 val code = state.verificationCode
if (code == null) { if (code == null) {
Text( Text(
@ -97,6 +101,7 @@ fun RestoreRequestScreen(
@Composable @Composable
fun RestoreConsentScreen( fun RestoreConsentScreen(
onDone: () -> Unit, onDone: () -> Unit,
onBack: () -> Unit = {},
viewModel: RestoreViewModel = hiltViewModel() viewModel: RestoreViewModel = hiltViewModel()
) { ) {
val state by viewModel.uiState.collectAsState() val state by viewModel.uiState.collectAsState()
@ -105,7 +110,7 @@ fun RestoreConsentScreen(
LaunchedEffect(state.consentComplete) { if (state.consentComplete) onDone() } LaunchedEffect(state.consentComplete) { if (state.consentComplete) onDone() }
LaunchedEffect(state.error) { state.error?.let { snackbar.showSnackbar(it); viewModel.dismissError() } } 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 { when {
// Wait for the first observation before deciding what to show (avoids flashing "no request"). // Wait for the first observation before deciding what to show (avoids flashing "no request").
!state.consentChecked -> { !state.consentChecked -> {
@ -222,6 +227,7 @@ private fun RestoreScaffold(
snackbar: SnackbarHostState, snackbar: SnackbarHostState,
icon: androidx.compose.ui.graphics.vector.ImageVector, icon: androidx.compose.ui.graphics.vector.ImageVector,
title: String, title: String,
onBack: (() -> Unit)? = null,
content: @Composable () -> Unit content: @Composable () -> Unit
) { ) {
Scaffold( Scaffold(
@ -240,7 +246,15 @@ private fun RestoreScaffold(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top 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)) StatusGlyph(icon = icon, tint = SettingsPrimaryDeep, container = SettingsPrimary.copy(alpha = 0.12f))
Spacer(Modifier.height(20.dp)) Spacer(Modifier.height(20.dp))
Text(title, style = MaterialTheme.typography.headlineSmall, color = SettingsInk, Text(title, style = MaterialTheme.typography.headlineSmall, color = SettingsInk,