65202b932d76
feat: organize Vault settings card into collapsible groups (v2.10.21)
- time
- 2026-08-04 14:59 UTC · 2 months ago
- machine
- koh2
- parent
- 6f9ce481dbfb
↓ peach-android-65202b93.tar.gzatlas at this save
files changed2 files
VERSION+1 −1app/src/main/java/com/peachpasswords/ui/settings/SettingsCardBodies.kt+51 −13app/src/main/java/com/peachpasswords/ui/settings/SettingsCardBodies.kt+51 −13
@@ -122,7 +122,46 @@122122 )123123 }124124 125+/**126+ * Collapsible group inside a card body: the uppercase heading row toggles its127+ * rows, so busy cards can fold rarely-used sections away. Groups holding128+ * dangerous or rarely-used actions start collapsed.129+ */125130 @Composable131+private fun SettingsGroup(132+ label: String,133+ fg: Color,134+ initiallyOpen: Boolean = true,135+ top: Dp = 14.dp,136+ content: @Composable () -> Unit,137+) {138+ var open by remember { mutableStateOf(initiallyOpen) }139+ Row(140+ Modifier.fillMaxWidth()141+ .clip(RoundedCornerShape(6.dp))142+ .clickable { open = !open }143+ .padding(top = top, bottom = 4.dp),144+ verticalAlignment = Alignment.CenterVertically,145+ ) {146+ Text(147+ label,148+ modifier = Modifier.weight(1f),149+ color = fg.copy(alpha = 0.58f),150+ fontFamily = PeachType.Mono,151+ fontSize = 8.sp,152+ letterSpacing = 0.22.em,153+ )154+ Text(155+ if (open) "–" else "+",156+ color = fg.copy(alpha = 0.58f),157+ fontFamily = PeachType.Mono,158+ fontSize = 10.sp,159+ )160+ }161+ AnimatedVisibility(visible = open) { content() }162+}163+164+@Composable126165 private fun RowLine(127166 fg: Color,128167 modifier: Modifier = Modifier,@@ -547,7 +586,7 @@547586 val history by vm.vaultHistory.collectAsState()548587 val restoringSnapshotId by vm.restoringSnapshotId.collectAsState()549588 550- SubLabel("ENTRIES", fg, top = 0.dp)589+ SettingsGroup("ENTRIES", fg, top = 0.dp) {551590 RowLine(fg) { Name("Entries", fg); ValueText("$entriesCount", fg) }552591 RowLine(fg) {553592 Name("Duplicates", fg)@@ -591,8 +630,9 @@591630 }592631 }593632 }633+ }594634 595- SubLabel("MAINTENANCE", fg)635+ SettingsGroup("MAINTENANCE", fg) {596636 RowLine(fg) {597637 Name("Trash auto-delete", fg)598638 val idx = trashOptions.indexOfFirst { it.first == current }.coerceAtLeast(0)@@ -602,8 +642,9 @@602642 }603643 RowLine(fg) { Name("Advanced Vault Health", fg); SubtleButton("open", fg) { onNavigate(PeachNav.Health) } }604644 RowLine(fg) { Name("Trash", fg); SubtleButton("open", fg) { onNavigate(PeachNav.Trash) } }645+ }605646 606- SubLabel("DATA", fg)647+ SettingsGroup("DATA", fg) {607648 RowLine(fg) { Name("Import passwords", fg); SubtleButton("open", fg) { onNavigate(PeachNav.Import) } }608649 RowLine(fg) { Name("Export backup", fg); SubtleButton("open", fg) { onNavigate(PeachNav.Export) } }609650 RowLine(fg) {@@ -611,12 +652,14 @@611652 SubtleButton(if (isPro) "open" else "Pro", fg) { if (isPro) onNavigate(PeachNav.CodexGenerate) }612653 }613654 RowLine(fg) { Name("Restore from Codex", fg); SubtleButton("open", fg) { onNavigate(PeachNav.CodexRestore) } }655+ }614656 615- var historyShowAll by remember { mutableStateOf(false) }616- SubLabel("UPDATES", fg)657+ SettingsGroup("UPDATES", fg) {617658 UpdatesRows(fg, onNavigate)659+ }618660 619- SubLabel("VAULT HISTORY", fg)661+ SettingsGroup("VAULT HISTORY", fg, initiallyOpen = false) {662+ var historyShowAll by remember { mutableStateOf(false) }620663 if (history.isEmpty()) {621664 Text(622665 "No snapshots yet. Peach saves automatically before every change — saves, syncs, and imports.",@@ -660,14 +703,9 @@660703 modifier = Modifier.padding(top = 2.dp, bottom = 6.dp),661704 )662705 }663-664- var advancedOpen by remember { mutableStateOf(false) }665- SubLabel("ADVANCED", fg)666- RowLine(fg) {667- Name("Advanced", fg)668- SubtleButton(if (advancedOpen) "hide" else "show", fg) { advancedOpen = !advancedOpen }669706 }670- if (advancedOpen) {707+708+ SettingsGroup("ADVANCED", fg, initiallyOpen = false) {671709 RowLine(fg) {672710 Name("Replace vault from backup", com.peachpasswords.ui.theme.peachColors.SyncBusy)673711 SubtleButton("open", com.peachpasswords.ui.theme.peachColors.SyncBusy) { onNavigate(PeachNav.Import) }