Skip to content

Fix paused and done dark modes on sync screen - #148

Open
chaitika wants to merge 2 commits into
CypherCommons:masterfrom
chaitika:add/sync-dark-mode
Open

Fix paused and done dark modes on sync screen#148
chaitika wants to merge 2 commits into
CypherCommons:masterfrom
chaitika:add/sync-dark-mode

Conversation

@chaitika

@chaitika chaitika commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Scan State

Current View image image image image
Updated View image image image image

Paused State

Current View imageimageimageimage
Updated View image image image image

Done State

Current View imageimage image image
Updated View image image imageimage

Copilot AI lite review requested due to automatic review settings August 25, 2026 15:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@chaitika chaitika changed the title Dark mode support for sync/scan screens FIX: header background mismatch + paused/error icon dark mode on sync screens Aug 25, 2026
@chaitika chaitika changed the title FIX: header background mismatch + paused/error icon dark mode on sync screens Fix paused dark mode on sync screen Aug 25, 2026
Adds dark-mode color tokens for the scan banner's paused state (custom
pause icon) and the SyncStatusIcon paused/error glyphs. Also fixes
header backgrounds defaulting to React Navigation's card color instead
of the screen background app-wide, and adds a scan-rate (blk/s)
readout to the Update Progress card.
@chaitika
chaitika force-pushed the add/sync-dark-mode branch from 85e305f to cf967f1 Compare August 25, 2026 15:43
Adds dark-mode tokens for the scanning and done SyncStatusIcon states
(previously same() light-only colors), replaces the Material check-circle
and refresh glyphs with custom SVG icons (CheckIcon, RetryIcon) matching
design, fixes the pause/check-again button borders and check-again
text/icon color to be theme-aware, and makes the sync-screen percent
sign switch to black/white at 100% done while staying grey mid-scan.
Copilot AI review requested due to automatic review settings August 25, 2026 18:03

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@chaitika chaitika changed the title Fix paused dark mode on sync screen Fix paused and done dark modes on sync screen Aug 25, 2026
Comment thread components/themes.ts
Comment on lines +138 to +149
syncOuterScanning: pair(palette.white, '#0D0D0D'), // scanning-state icon backing circle
syncFillScanning: pair('#DCD2F9', '#3A3166'),
syncRingPaused: pair('#E6E4E499', '#FFFFFF14'), // alpha baked in: 0.6 opacity light, 0.08 opacity dark
syncFillPaused: pair('#F5F5F7', '#1A1A28'),
syncOuterPaused: pair(palette.white, '#0E0E16'), // paused-state icon backing circle
syncGlyphPaused: pair('#8E8E93', '#8888AA'), // paused-state pause glyph
syncOuterDone: pair(palette.white, '#0D0D0D'), // done-state icon backing circle
syncRingDone: pair('#E2FAEA', '#16301F'),
syncFillDone: pair('#D2F9DC', '#1C3D28'),
syncRingError: pair('#FDF1F2', '#330C09'),
syncFillError: pair('#FBE9EB', '#3E0B0B'),
syncOuterError: pair(palette.white, '#0D0D0D'), // error-state icon backing circle

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syncOuterScanning, syncOuterDone and syncOuterError are all pair(palette.white, '#0D0D0D') — identical to each other, and identical to background: pair(palette.white, palette.gray950) now that gray950 is #0D0D0D (there's a fourth copy at searchIconBackground). The backing circle behind the sync icon is the page background; it should reference colors.background rather than restate the literal three times, otherwise the next background change silently desyncs four tokens.

syncOuterPaused is #0E0E16 — a sub-perceptual delta from #0D0D0D that looks like a Figma export artifact. Because it's a filled circle sitting on the background, this is the one case where an off-by-one-shade fill actually renders: a faint disc edge on the paused state that the other three states won't have. Please make all four the same value.

Comment thread components/themes.ts
Comment on lines +110 to +111
surfaceSubtle: pair(palette.violet50, palette.violet900), // banner / card background
accentSubtle: pair(palette.violet100, '#2D264F'), // banner & card border, "check again" button bg, scanning icon ring

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two are now exact duplicates of tokens already in this file:

  • surfaceSubtle: pair(palette.violet50, palette.violet900) == bannerBackground (L152)
  • accentSubtle: pair(palette.violet100, '#2D264F') == bannerBorderColor (L155)

Worth collapsing rather than keeping two names per value — otherwise a future tweak has to be applied twice to stay consistent.

Comment thread components/themes.ts
Comment on lines +112 to +115
checkAgainButtonColor: pair(palette.violet600, palette.white), // "check again" button icon + text
progressCardBackground: pair(palette.violet50, '#1A1535'), // sync screen "Update Progress" / privacy card background
progressCardBorder: pair(palette.violet100, '#25253A'), // sync screen "Update Progress" / privacy card border
pausedIconColor: pair('#1A1A1A', '#F0F0F5'), // paused-state pause icon on the sync banner

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are named after the single control that consumes them (checkAgainButtonColor, progressCardBackground, progressCardBorder, pausedIconColor, and continueButtonBorder/retryButtonBorder/syncPercentSignColor below). The block directly above — textPrimary, textSecondary, surfaceSubtle, accentSubtle — is role-based, which is what makes it reusable. Once a token is called checkAgainButtonColor, the next control that wants the same treatment either gets a second token or an obviously-wrong reference. Could these be expressed as roles (e.g. onBrandSurface, surfaceRaised, surfaceRaisedBorder)?

Separately, these lines introduce raw hex (#1A1535, #25253A, #F0F0F5) rather than going through palette at the top of the file. There are ~16 new literals across this hunk, several repeated across tokens — #1A1535 also appears in progressTrack (L123), #F0F0F5 in syncPercentColor (L131), #8888AA twice (L132, L143).

Comment thread components/themes.ts
pausedIconColor: pair('#1A1A1A', '#F0F0F5'), // paused-state pause icon on the sync banner
surfaceCaution: same('#FDFBF5'), // caution banner background (address-reuse warning)
iconCaution: same('#F1AF63'), // caution banner icon (warm amber)
errorBannerText: pair('#B24334', '#C54A3A'), // "can't connect" sync status icon glyph

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name/usage mismatch: the token is called errorBannerText, but the comment and the only consumer (SyncStatusIcon.tsx:40) say it's an SVG glyph fill, not banner text.

Comment thread components/themes.ts
copyHint: same(palette.gray450), // "tap to copy" icon + label
progressTrack: same('#EAECF0'),
progressTrack: pair('#EAECF0', '#1A1535'),
buttonBorder: same('#EBEBEB'),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

buttonBorder has zero references left in the repo after this PR — the three call sites in SyncScreen.tsx were the last ones and all moved to continueButtonBorder/retryButtonBorder. Same for statusPaused (L107), whose last consumers moved to pausedIconColor and syncGlyphPaused.

Preferred fix is to widen these two in place (give them dark values) instead of adding parallel tokens; failing that, please delete them.

<Text style={[styles.percentSign, { color: colors.textMeta }]}>%</Text>
<Text style={[styles.percentNum, { color: colors.syncPercentColor }]}>{Math.round(effectivePct)}</Text>
<Text
style={[styles.percentSign, { color: effectiveStatus === 'done' ? colors.syncPercentColor : colors.syncPercentSignColor }]}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every other status-dependent colour on this screen goes through a lookup (SyncStatusIcon's iconColors) or the switch in renderTitle/renderActionButton. This inline ternary is the odd one out — and it's the second place that has to be updated when a status is added.

Comment on lines +250 to +255
<View style={styles.cardRow}>
<Text style={[styles.cardLabel, { color: colors.textMuted }]}>{loc.sync.scan_rate_label}</Text>
<Text style={[styles.cardValue, styles.cardValueSemibold, { color: colors.textPrimary }]} numberOfLines={1}>
{scanState.scanRate !== null ? loc.formatString(loc.sync.scan_rate_value, { rate: scanState.scanRate }) : '--'}
</Text>
</View>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This card renders for paused as well as scanning (L229), but pauseScan() (hd-bip352-wallet.ts:136) emits 'paused' without clearing scanRate. So a paused screen shows the title "Paused" above a live-looking "12 blk/s". resumeScan() already clears _scanSamples correctly (:143); pauseScan() just needs to null scanRate alongside it, or this row should be hidden while paused.

Comment on lines +615 to +618
const blocksGained = newest.block - oldest.block;
if (elapsedMs > 0 && blocksGained > 0) {
scanRate = Math.round(blocksGained / (elapsedMs / 1000));
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two rough edges in how this reaches the UI:

  • Math.round floors anything under 0.5 blk/s to 0 blk/s, which reads as "stalled" on exactly the slow scans where the user is most likely to be watching this number.
  • The blocksGained > 0 guard leaves scanRate null whenever the rolling window hasn't advanced a block, and the UI renders that as -- (SyncScreen.tsx:253). Combined with the point above, the row alternates between a number, 0, and --.

A one-decimal value below 1, or holding the last known rate instead of dropping to null, would be steadier.

Comment thread loc/en.json
"done": "You're all caught up",
"error_title": "Can't connect right now",
"error_description": "Shroud can't update right now, but your Bitcoin is secure.",
"error_description": "Shroud can't update right now,\nbut your Bitcoin is secure.",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded \n puts layout into the copy. Where the line should break is a function of container width and font scale, not of the string — and it'll be wrong for any locale added later. en is the only locale today so the impact is small, but this belongs in the style (width constraint / textAlign) rather than the content.

startedAt: number | null;
eta: number | null;
etaComputedAt: number | null;
scanRate: number | null;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scope: the scan-rate metric is a new user-facing feature threaded through ScanStateInfo -> the wallet class -> loc -> the UI, in a PR titled "Fix paused and done dark modes on sync screen". It's also the only part of the diff with runtime behaviour to verify, and the screenshots don't cover it. Could it go out as its own PR so the dark-mode change stays reviewable on its screenshots alone?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants