Files
thoughtsync/android/app/src/main
bvandeusen 64542ed6cb
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 3m18s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 5m35s
Desktop (Tauri) / Update manifest (push) Successful in 6s
Android / Kotlin + Rust (debug APK) (push) Successful in 7m56s
android: pull the board down to sync (M12 step 6)
Every sync so far has been a button press on a screen you have to navigate to.
On a phone the gesture for "check if there's anything new" is a pull, and not
having it is the kind of absence people read as the app not syncing at all.

**The gesture is INERT when this device has no server.** `Modifier.pullToRefresh`
takes an `enabled`, which is why the modifier and the indicator are wired by hand
instead of using `PullToRefreshBox` — that wrapper is less code and offers no way
to turn the gesture off. An unlinked device has nowhere to pull from, and a
gesture that always comes back empty is how people learn a control is broken.
Same reasoning as the drawer badge staying silent when unlinked: local-only is
this app's resting state, not a fault.

**A failed refresh reaches the board.** Otherwise the spinner retracts and
nothing happens, which is indistinguishable from "you were already up to date" —
the one outcome it must not be confused with. It renders as a second banner
rather than replacing the store-error one: those are different facts about
different halves of the app, and hiding either behind the other reports the
wrong problem. Dismissing is honest — the note is still pending, `hasPending`
still says so, and the next cycle reports the same fault if it persists.

**The empty board is now a `LazyColumn` holding one centred item.** Pull-to-
refresh works through nested scroll, and a layout that never scrolls never
dispatches any, so on the old plain `Column` the gesture would have been dead on
exactly the screen where it matters most: linked, board empty, notes still on the
server. Looks identical.

The five sync facts the board needs arrive as one `BoardSync` rather than five
parameters, for the reason `EditorAction` exists: `summary` and `error` are both
`String?` and both about sync, so positionally they could be swapped with nothing
to catch it.

Still no automatic sync — no background cycle, no sync-on-resume. This is a
faster way to ask, not a decision to stop asking. TalkBack users cannot perform
a pull; the drawer's Sync → Sync now remains the accessible path, unchanged.

Verified against the real artifact rather than from memory, since `material3`
resolves through the BOM: 1.4.0's sources confirm `pullToRefresh` has `enabled`,
and that none of `pullToRefresh`, `rememberPullToRefreshState`, `Indicator` or
`PullToRefreshBox` is `@ExperimentalMaterial3Api` there — only two deprecated
members are. So no `@OptIn`, which is what keeps the build at zero warnings.
2026-08-19 16:36:56 -04:00
..