feat: convert AccountBackupDialog to a navigation Route

Replaces the local dialog state in AllSettingsScreen with a proper
Route.AccountBackup, presented as a bottom-slide composable.

- Add `Route.AccountBackup` to Routes.kt (sealed class + getRouteWithArguments)
- Rename `AccountBackupDialog` → `AccountBackupScreen` accepting `INav` instead of `onClose`; remove Dialog wrapper
- Register `composableFromBottom<Route.AccountBackup>` in AppNavigation
- Update AllSettingsScreen to navigate to Route.AccountBackup instead of managing local dialog state

https://claude.ai/code/session_01KRRANB1b7wV7mpxEvpfjc7
This commit is contained in:
Claude
2026-03-03 15:43:18 +00:00
parent 3c32dbc701
commit 9910bd0dfa
4 changed files with 13 additions and 24 deletions
@@ -105,6 +105,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.relay.RelayFeedScreen
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.AllRelayListScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.AllRelayListScreen
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.RelayInformationScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.RelayInformationScreen
import com.vitorpamplona.amethyst.ui.screen.loggedIn.search.SearchScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.search.SearchScreen
import com.vitorpamplona.amethyst.ui.screen.loggedIn.keyBackup.AccountBackupScreen
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.AllSettingsScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.AllSettingsScreen
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.NIP47SetupScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.NIP47SetupScreen
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SecurityFiltersScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SecurityFiltersScreen
@@ -165,6 +166,7 @@ fun AppNavigation(
composable<Route.Search> { SearchScreen(accountViewModel, nav) } composable<Route.Search> { SearchScreen(accountViewModel, nav) }
composableFromEnd<Route.AllSettings> { AllSettingsScreen(accountViewModel, nav) } composableFromEnd<Route.AllSettings> { AllSettingsScreen(accountViewModel, nav) }
composableFromBottom<Route.AccountBackup> { AccountBackupScreen(accountViewModel, nav) }
composableFromEnd<Route.SecurityFilters> { SecurityFiltersScreen(accountViewModel, nav) } composableFromEnd<Route.SecurityFilters> { SecurityFiltersScreen(accountViewModel, nav) }
composableFromEnd<Route.PrivacyOptions> { PrivacyOptionsScreen(Amethyst.instance.torPrefs.value, nav) } composableFromEnd<Route.PrivacyOptions> { PrivacyOptionsScreen(Amethyst.instance.torPrefs.value, nav) }
composableFromEnd<Route.Bookmarks> { BookmarkListScreen(accountViewModel, nav) } composableFromEnd<Route.Bookmarks> { BookmarkListScreen(accountViewModel, nav) }
@@ -81,6 +81,8 @@ sealed class Route {
@Serializable object AllSettings : Route() @Serializable object AllSettings : Route()
@Serializable object AccountBackup : Route()
@Serializable object Settings : Route() @Serializable object Settings : Route()
@Serializable object UserSettings : Route() @Serializable object UserSettings : Route()
@@ -332,6 +334,7 @@ fun getRouteWithArguments(navController: NavHostController): Route? {
dest.hasRoute<Route.ContentDiscovery>() -> entry.toRoute<Route.ContentDiscovery>() dest.hasRoute<Route.ContentDiscovery>() -> entry.toRoute<Route.ContentDiscovery>()
dest.hasRoute<Route.Drafts>() -> entry.toRoute<Route.Drafts>() dest.hasRoute<Route.Drafts>() -> entry.toRoute<Route.Drafts>()
dest.hasRoute<Route.AllSettings>() -> entry.toRoute<Route.AllSettings>() dest.hasRoute<Route.AllSettings>() -> entry.toRoute<Route.AllSettings>()
dest.hasRoute<Route.AccountBackup>() -> entry.toRoute<Route.AccountBackup>()
dest.hasRoute<Route.Settings>() -> entry.toRoute<Route.Settings>() dest.hasRoute<Route.Settings>() -> entry.toRoute<Route.Settings>()
dest.hasRoute<Route.EditProfile>() -> entry.toRoute<Route.EditProfile>() dest.hasRoute<Route.EditProfile>() -> entry.toRoute<Route.EditProfile>()
dest.hasRoute<Route.Profile>() -> entry.toRoute<Route.Profile>() dest.hasRoute<Route.Profile>() -> entry.toRoute<Route.Profile>()
@@ -80,8 +80,6 @@ import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import com.halilibo.richtext.commonmark.CommonMarkdownParseOptions import com.halilibo.richtext.commonmark.CommonMarkdownParseOptions
import com.halilibo.richtext.commonmark.CommonmarkAstNodeParser import com.halilibo.richtext.commonmark.CommonmarkAstNodeParser
@@ -91,6 +89,7 @@ import com.halilibo.richtext.ui.material3.RichText
import com.halilibo.richtext.ui.resolveDefaults import com.halilibo.richtext.ui.resolveDefaults
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon
import com.vitorpamplona.amethyst.ui.note.authenticate import com.vitorpamplona.amethyst.ui.note.authenticate
import com.vitorpamplona.amethyst.ui.painterRes import com.vitorpamplona.amethyst.ui.painterRes
@@ -112,23 +111,18 @@ import kotlinx.coroutines.launch
@OptIn(ExperimentalComposeUiApi::class) @OptIn(ExperimentalComposeUiApi::class)
@Composable @Composable
fun AccountBackupDialog( fun AccountBackupScreen(
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
onClose: () -> Unit, nav: INav,
) { ) {
Dialog( AccountBackupScreenContent(accountViewModel, nav::popBack)
onDismissRequest = onClose,
properties = DialogProperties(usePlatformDefaultWidth = false),
) {
DialogContents(accountViewModel, onClose)
}
} }
@Preview(device = "spec:width=2160px,height=2340px,dpi=440") @Preview(device = "spec:width=2160px,height=2340px,dpi=440")
@Composable @Composable
fun DialogContentsPreview() { fun AccountBackupScreenPreview() {
ThemeComparisonRow { ThemeComparisonRow {
DialogContents( AccountBackupScreenContent(
mockAccountViewModel(), mockAccountViewModel(),
) {} ) {}
} }
@@ -136,7 +130,7 @@ fun DialogContentsPreview() {
@OptIn(ExperimentalComposeUiApi::class) @OptIn(ExperimentalComposeUiApi::class)
@Composable @Composable
private fun DialogContents( private fun AccountBackupScreenContent(
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
onClose: () -> Unit, onClose: () -> Unit,
) { ) {
@@ -61,7 +61,6 @@ import com.vitorpamplona.amethyst.ui.note.UpdateReactionTypeDialog
import com.vitorpamplona.amethyst.ui.note.UpdateZapAmountDialog import com.vitorpamplona.amethyst.ui.note.UpdateZapAmountDialog
import com.vitorpamplona.amethyst.ui.painterRes import com.vitorpamplona.amethyst.ui.painterRes
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.keyBackup.AccountBackupDialog
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn
@@ -152,22 +151,13 @@ fun AllSettingsScreen(
onClick = { nav.nav(Route.UserSettings) }, onClick = { nav.nav(Route.UserSettings) },
) )
accountViewModel.account.settings.keyPair.privKey?.let { accountViewModel.account.settings.keyPair.privKey?.let {
var backupDialogOpen by remember { mutableStateOf(false) }
HorizontalDivider() HorizontalDivider()
SettingsNavigationRow( SettingsNavigationRow(
title = R.string.backup_keys, title = R.string.backup_keys,
icon = Icons.Outlined.Key, icon = Icons.Outlined.Key,
tint = tint, tint = tint,
onClick = { onClick = { nav.nav(Route.AccountBackup) },
nav.closeDrawer()
backupDialogOpen = true
},
) )
if (backupDialogOpen) {
AccountBackupDialog(accountViewModel, onClose = { backupDialogOpen = false })
}
} }
HorizontalDivider(thickness = 4.dp) HorizontalDivider(thickness = 4.dp)
SettingsSectionHeader(R.string.app_settings) SettingsSectionHeader(R.string.app_settings)