Skip to content

Commit 0185676

Browse files
committed
Implement sync error auto-show logic and add unit tests for error visibility conditions
1 parent c61d2f0 commit 0185676

3 files changed

Lines changed: 37 additions & 2 deletions

File tree

app/src/main/java/cash/p/terminal/modules/balance/token/TokenBalanceScreen.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ import cash.p.terminal.ui.compose.components.BadgeText
7979
import cash.p.terminal.ui.compose.components.CoinIconWithSyncProgress
8080
import cash.p.terminal.ui.compose.components.ListEmptyView
8181
import cash.p.terminal.ui_compose.CoinFragmentInput
82+
import cash.p.terminal.ui_compose.ScreenSecurityState
8283
import cash.p.terminal.ui_compose.components.AppBar
8384
import cash.p.terminal.ui_compose.components.ButtonPrimaryCircle
8485
import cash.p.terminal.ui_compose.components.ButtonPrimaryDefault
@@ -124,8 +125,9 @@ fun TokenBalanceScreen(
124125
val loading = uiState.balanceViewItem?.syncingProgress?.progress != null
125126

126127
LaunchedEffect(failedIconVisible) {
127-
if (failedIconVisible) {
128-
onSyncErrorClicked(uiState.balanceViewItem, viewModel, navController)
128+
val viewItem = uiState.balanceViewItem
129+
if (viewItem != null && shouldAutoShowSyncError(failedIconVisible, ScreenSecurityState.isAppLocked)) {
130+
onSyncErrorClicked(viewItem, viewModel, navController)
129131
}
130132
}
131133

@@ -654,6 +656,11 @@ private fun LockedBalanceCell(
654656
}
655657
}
656658

659+
// Never auto-open the wallet sync-error sheet while the app is locked: it lives in its
660+
// own Window and would leak wallet UI above the calculator/PIN disguise (deanonymization).
661+
internal fun shouldAutoShowSyncError(failedIconVisible: Boolean, appLocked: Boolean): Boolean =
662+
failedIconVisible && !appLocked
663+
657664
private fun onSyncErrorClicked(
658665
viewItem: BalanceViewItem,
659666
viewModel: TokenBalanceViewModel,

app/src/main/java/cash/p/terminal/modules/main/MainActivity.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ open class MainActivity : BaseActivity() {
6969
showPinLockScreen = false
7070
pinLockComposeView?.visibility = GONE
7171
applyLockWindowFlags(isLocked = false, calculatorMode = true)
72+
} else if (pinComponent.isLockedFlow.value) {
73+
// Locked on return: a dialog left open in the background lives in its own
74+
// Window and would surface above the calculator/PIN disguise. The collect in
75+
// observeLockState reacts asynchronously, so close synchronously here too.
76+
closeWindowsAboveLockScreen()
7277
}
7378
validate()
7479
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package cash.p.terminal.modules.balance.token
2+
3+
import org.junit.Assert.assertFalse
4+
import org.junit.Assert.assertTrue
5+
import org.junit.Test
6+
7+
class SyncErrorAutoShowGuardTest {
8+
9+
@Test
10+
fun shouldAutoShowSyncError_failedAndUnlocked_returnsTrue() {
11+
assertTrue(shouldAutoShowSyncError(failedIconVisible = true, appLocked = false))
12+
}
13+
14+
@Test
15+
fun shouldAutoShowSyncError_failedAndLocked_returnsFalse() {
16+
assertFalse(shouldAutoShowSyncError(failedIconVisible = true, appLocked = true))
17+
}
18+
19+
@Test
20+
fun shouldAutoShowSyncError_notFailedAndUnlocked_returnsFalse() {
21+
assertFalse(shouldAutoShowSyncError(failedIconVisible = false, appLocked = false))
22+
}
23+
}

0 commit comments

Comments
 (0)