Sync UI preferences across devices via UserSettings #60
Labels
No labels
adr
android
area/calendar
area/design-system
area/i18n
area/jobs
area/offline
area/server
area/testing
bug
ci
duplicate
enhancement
help wanted
invalid
notifications
question
reliability
security
severity/low
severity/medium
tracking
web
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
eagraiclainne/app#60
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Sync every per-member UI preference across a member's devices through
UserSettings. Today theme family, mode, custom tokens, locale, and tour-seen version already sync. Text scale and reduce-motion do not — they live only in the device-localeagraiclainne.prefs.<uid>bag. Bring those into the synced model, add a card-tilt flag for #48 to build on, and make the server the source of truth with localStorage demoted to a device cache.Motivation
A member who sets their text scale, motion, or theme on one device expects the same on every device. Theme already behaves that way. Text scale and reduce-motion do not, because they were never added to the proto. This is a split-brain: half the display preferences sync, half reset per device.
Current state:
proto/api/core/v1/user.proto):UserTheme.family,UserTheme.mode,UserTheme.custom_tokens,UserSettings.locale,UserSettings.tour_seen_version.web/src/theme/theme.tsx:22-23, theeagraiclainne.prefs.<uid>bag):textScale,reduceMotion. Not in the proto, never synced.Proposed design
Extend
UserSettingswith the display preferences that are missing:flatten_cardsis the knob #48 needs. It is defined here so the tilt work rides on this synced model instead of a new local flag.Source of truth and cache:
UserService.UpdateRPC and thesvc.Mutateseam. No new RPC.Migration:
Scope
Proto and server:
UserSettings(TextScaleenum, two bools). Regenerate Go, TypeScript, and Android.UserService.Updateaccepts and persists them through the mutation seam. No sensitive fields, no scrub-map change.Web (reference surface):
Android:
SessionStoreas the device cache.Open questions for the ADR
text_scaleas aTextScaleenum (validated set 1.0 / 1.15 / 1.33) versus a rawdouble. Recommendation: enum, to keep the validated set the web already uses.ADR
Add
docs/adr/00NN-sync-ui-preferences.md. Record the schema addition, the server-as-source-of-truth decision, the localStorage-as-cache role, the migration, and the conflict rule. Number it after the push ADR (0028) once that lands.Surface parity
Web is the reference. Android carries the same three synced preferences. MCP and CLI do not carry UI preferences. Per system rule 1.
CLAUDE.md
The frontend section currently states that scale and motion persist in namespaced localStorage. Update it to say the server record is the source of truth and localStorage is the device cache (system rule 5).
Blocks
flatten_cardsfield defined here.Definition of done
text_scale,reduce_motion, andflatten_cardssync across a member's devices.make checkpasses. Verified across two devices against the live deploy.