d7406e5e9d9d

fix: Collapse stacked sync updates in the vault (v2.5.23)

time
2026-07-27 19:46 UTC · 2 months ago
machine
koh2
parent
d620000dab23
3 files app/build.gradle+2 −2app/src/main/java/com/peachpasswords/ui/vault/VaultListScreen.kt+31 −1app/src/test/java/com/peachpasswords/ui/vault/VaultListSyncAlertTest.kt+29 −0
app/build.gradle+2 −2
@@ -16,8 +16,8 @@1616         applicationId "com.peachpasswords"1717         minSdk 261818         targetSdk 3519-        versionCode 24012220-        versionName "2.5.22"19+        versionCode 24012320+        versionName "2.5.23"2121 2222         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"2323         vectorDrawables {

view file

app/src/main/java/com/peachpasswords/ui/vault/VaultListScreen.kt+31 −1
@@ -386,19 +386,46 @@386386 @Composable387387 private fun SyncAlertBanners(alerts: List<SyncAlert>, onDismiss: (SyncAlert) -> Unit) {388388     if (alerts.isEmpty()) return389+    var expanded by remember(alerts) { mutableStateOf(false) }389390     Column(390391         modifier = Modifier391392             .fillMaxWidth()392393             .padding(horizontal = 16.dp, vertical = 6.dp),393394         verticalArrangement = Arrangement.spacedBy(6.dp),394395     ) {395-        alerts.forEach { alert ->396+        if (alerts.size > 1) {396397             Row(397398                 modifier = Modifier398399                     .fillMaxWidth()400+                    .heightIn(min = 48.dp)399401                     .clip(RoundedCornerShape(8.dp))400402                     .background(peachColors.SurfaceElevated)401403                     .border(1.dp, peachColors.T3, RoundedCornerShape(8.dp))404+                    .clickable { expanded = !expanded }405+                    .padding(horizontal = 12.dp),406+                verticalAlignment = Alignment.CenterVertically,407+            ) {408+                Text(409+                    text = "${alerts.size} sync updates",410+                    color = peachColors.T1,411+                    style = PeachType.bodyMono.copy(fontSize = 11.sp),412+                    modifier = Modifier.weight(1f),413+                )414+                Text(415+                    text = if (expanded) "hide" else "show",416+                    color = LocalPeachAccent.current,417+                    style = PeachType.labelMono.copy(fontSize = 10.sp),418+                )419+            }420+        }421+        visibleSyncAlerts(alerts, expanded).forEach { alert ->422+            Row(423+                modifier = Modifier424+                    .fillMaxWidth()425+                    .heightIn(min = 48.dp)426+                    .clip(RoundedCornerShape(8.dp))427+                    .background(peachColors.SurfaceElevated)428+                    .border(1.dp, peachColors.T3, RoundedCornerShape(8.dp))402429                     .padding(start = 12.dp, top = 9.dp, end = 8.dp, bottom = 9.dp),403430                 verticalAlignment = Alignment.CenterVertically,404431             ) {@@ -422,6 +449,9 @@422449         }423450     }424451 }452+453+internal fun visibleSyncAlerts(alerts: List<SyncAlert>, expanded: Boolean): List<SyncAlert> =454+    if (alerts.size <= 1 || expanded) alerts else emptyList()425455 426456 private fun pluralEntries(total: Int): String = if (total == 1) "1 entry" else "$total entries"427457 

view file

app/src/test/java/com/peachpasswords/ui/vault/VaultListSyncAlertTest.kt+29 −0
@@ -0,0 +1,29 @@1+package com.peachpasswords.ui.vault2+3+import com.peachpasswords.sync.SyncAlert4+import com.peachpasswords.sync.SyncAlertType5+import org.junit.Assert.assertEquals6+import org.junit.Assert.assertTrue7+import org.junit.Test8+9+class VaultListSyncAlertTest {10+    private fun alert(timestamp: Long) = SyncAlert(11+        type = SyncAlertType.REMOTE_DELETE,12+        entryTitle = "Entry $timestamp",13+        deviceName = "Extension",14+        timestamp = timestamp,15+    )16+17+    @Test fun one_update_stays_visible_without_an_extra_summary_row() {18+        val alerts = listOf(alert(1L))19+20+        assertEquals(alerts, visibleSyncAlerts(alerts, expanded = false))21+    }22+23+    @Test fun multiple_updates_are_compact_until_expanded() {24+        val alerts = listOf(alert(1L), alert(2L), alert(3L))25+26+        assertTrue(visibleSyncAlerts(alerts, expanded = false).isEmpty())27+        assertEquals(alerts, visibleSyncAlerts(alerts, expanded = true))28+    }29+}

view file