fix(ios): widget status derives from the issue list; readable light-mode green (#73, #74)#75
Conversation
…ode green (#73, #74) Ships in the not-yet-archived 1.8.0 (build 33 unchanged, never uploaded). #73: the widget snapshot only knew idle/syncing/error, so a parked share or a required peer offline beyond its grace period left a green "All Synced" on the home screen - the same lie-class #66 fixed for the in-app header. The snapshot tier now comes from SyncHeaderModel.deriveWidgetStatus: the header's own cascade (decision 012) with the vault-setup tiers pinned "armed", fed by the same unresolvedIssues list plus the freshly polled folder statuses (they arrive before folderStatuses is published). The private WidgetSnapshotStatus enum is gone; the snapshot persists SyncStatus.wireValue. Wire compatibility holds both ways: a stale "idle" snapshot still decodes to synced, and fromWire maps anything unknown to attention, so no combination can decode into a false green. Two visible tier changes, both deliberate and matching the header: folder errors now show amber "Needs Attention" (was red "Sync Error"), and a snapshot written while the engine is down shows "Starting" (was green idle). The new suite pins every tier, asserts widget == header across the full input matrix, and round-trips the wire encoding. #74: light-mode statusSuccess measured 3.38:1 on white (WCAG wants 4.5:1 for text) and colors the "N of M devices connected" line; now (26,120,78) = 5.47:1, with the Increase Contrast variant deepened to (17,95,60) = 7.70:1 so it still increases contrast over the darker base. Dark mode unchanged. Same class and remedy as #68's amber. No strings added (the widget's "Needs Attention" labels shipped with #66). No Go changes - the earlier-1.8.0 xcframework rebuild note still applies before archiving. Verified: full Xcode test plan green (iPhone 17 Pro simulator, 237/237 incl. the new #73 suite), design-token lint green, Localizable key counts identical (632 x 4 app, 16 x 4 widget), WCAG ratios computed for old and new values. Fixes #73 Fixes #74
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📜 Recent review details⏰ Context from checks skipped due to timeout. (1)
|
| Layer / File(s) | Summary |
|---|---|
SyncHeaderModel widget status helper ios/VaultSync/ViewModels/SyncHeaderModel.swift |
Adds deriveWidgetStatus(...) mapping widget inputs to the existing header precedence cascade, hard-coding vault-related fields. |
SyncthingManager widget snapshot refactor ios/VaultSync/Services/SyncthingManager.swift |
Removes WidgetSnapshotStatus enum; derives SyncStatus from issue severities, engine/user errors, unreachable folders, and syncing state; persists via wireValue. |
Widget status test coverage ios/VaultSyncTests/WidgetSnapshotStatusTests.swift |
New test suite covering tier precedence, syncing precedence, clean/non-running states, an exhaustive input matrix, and wire-value round-trip. |
Changelog entry CHANGELOG.md |
Documents the widget status fix (no more misleading green check). |
statusSuccess light-mode color fix
| Layer / File(s) | Summary |
|---|---|
statusSuccess RGB values ios/VaultSync/Resources/Theme.swift |
Updates light and lightHC RGB values for statusSuccess for better contrast; dark values unchanged. |
Estimated code review effort: 3 (Moderate) | ~25 minutes
Possibly related issues
- fix(ios): statusAttention amber fails WCAG contrast in light mode; status tokens lack Increase-Contrast variants #68: Prior fix touching the same statusSuccess/amber accessibility color tokens in Theme.swift; this PR extends that work to the green status color.
Poem
A widget once winked green, all clear,
while a peer sat offline, out of ear.
Now it checks the issue list too,
and paints its greens a darker hue.
🐰 No more false calm — status is true!
🚥 Pre-merge checks | ✅ 7
✅ Passed checks (7 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | The title is concise, conventional-commit style, and accurately summarizes the widget status and light-mode green fixes. |
| Linked Issues check | ✅ Passed | The PR satisfies #73 by deriving widget status from the issue list and #74 by darkening statusSuccess in light mode. |
| Out of Scope Changes check | ✅ Passed | The changes stay within the two linked fixes, with only related tests and changelog updates added. |
| No Private Note Leakage | ✅ Passed | The new widget snapshot only stores status, counts, and timestamps; the derivation reduces issues to severities/booleans and adds no sensitive logging or network paths. |
| Bounded Ios Background Work | ✅ Passed | No background-execution logic changed; this commit only updates widget status derivation, colors, and tests, so the background-work constraints aren’t implicated. |
| Bridge Contract Compatibility | ✅ Passed | Only widget/status UI logic changed; no Go bridge or SyncBridgeService API/JSON/empty-string conventions changed, and wire decoding still fails safe. |
✨ Finishing Touches
📝 Generate docstrings
- Create stacked PR
- Commit on current branch
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Commit unit tests in branch
fix/issue-73-74-widget-status-contrast
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands.


Ships in the not-yet-archived 1.8.0 (build 33 unchanged, never uploaded).
#73: the widget snapshot only knew idle/syncing/error, so a parked share or
a required peer offline beyond its grace period left a green "All Synced"
on the home screen - the same lie-class #66 fixed for the in-app header.
The snapshot tier now comes from SyncHeaderModel.deriveWidgetStatus: the
header's own cascade (decision 012) with the vault-setup tiers pinned
"armed", fed by the same unresolvedIssues list plus the freshly polled
folder statuses (they arrive before folderStatuses is published). The
private WidgetSnapshotStatus enum is gone; the snapshot persists
SyncStatus.wireValue. Wire compatibility holds both ways: a stale "idle"
snapshot still decodes to synced, and fromWire maps anything unknown to
attention, so no combination can decode into a false green. Two visible
tier changes, both deliberate and matching the header: folder errors now
show amber "Needs Attention" (was red "Sync Error"), and a snapshot
written while the engine is down shows "Starting" (was green idle). The
new suite pins every tier, asserts widget == header across the full input
matrix, and round-trips the wire encoding.
#74: light-mode statusSuccess measured 3.38:1 on white (WCAG wants 4.5:1
for text) and colors the "N of M devices connected" line; now (26,120,78)
= 5.47:1, with the Increase Contrast variant deepened to (17,95,60) =
7.70:1 so it still increases contrast over the darker base. Dark mode
unchanged. Same class and remedy as #68's amber.
No strings added (the widget's "Needs Attention" labels shipped with #66).
No Go changes - the earlier-1.8.0 xcframework rebuild note still applies
before archiving.
Verified: full Xcode test plan green (iPhone 17 Pro simulator, 237/237
incl. the new #73 suite), design-token lint green, Localizable key counts
identical (632 x 4 app, 16 x 4 widget), WCAG ratios computed for old and
new values.
Fixes #73
Fixes #74
This PR fixes two iOS issues in the widget:
SyncStatus.wireValueand keeps older snapshots fail-safe.statusSuccesscolor used for the widget’s device-count text was darkened to meet WCAG contrast requirements, with the Increase Contrast variant updated as well. Dark mode is unchanged.No privacy/security or background-execution behavior changed. Test coverage was added for widget status precedence and wire-value round trips, and the Xcode test plan, design-token lint, and localization checks passed.