feat(settings): sync preferences across devices via io.lotus.settings account data (#104)
CI / Build & Quality Checks (push) Successful in 1m27s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 6s
CI / Trigger Desktop Build (push) Successful in 5s
CI / Playwright smoke (e2e) (push) Successful in 1m36s
CI / Build & Quality Checks (push) Successful in 1m27s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 6s
CI / Trigger Desktop Build (push) Successful in 5s
CI / Playwright smoke (e2e) (push) Successful in 1m36s
Every Lotus setting was localStorage-only, so a user on web + desktop + phone configured theme, composer toolbar, quiet hours, call keys… three times. - utils/settingsSync.ts (pure, 7 tests): DEVICE_LOCAL_KEYS denylist (zoom, media auto-load, animation pause, glassmorphism, denoise tier/model, bitrates, volumes, notification permission, developer tools, PTT mode, camera-on-join, drawer state, and the sync toggle itself), pickSyncable, mergeRemoteSettings (unknown keys, device-local keys and wrong-shaped values are skipped), buildSyncedContent, shouldApplyRemote (LWW on updatedAt; equal stamp = our own echo). - hooks/useSettingsSync.ts: on start applies a newer remote snapshot or pushes local if it differs; debounced push on any settingsAtom write, skipped when the syncable subset equals the last pushed/applied snapshot so a remote apply never echoes back; AccountData listener for live updates; stamps forced monotonic per device; per-account lastSyncedAt marker so another user on the same device can't inherit it; failed pushes roll the marker back so the next change retries. Remote values are re-read through getSettings() so enum coercion applies. - Settings → General → Sync: toggle (device-local), "Push now", "Clear synced copy". AccountDataEvent.LotusSettings registered. - ClientNonUIFeatures: the #103 tracking-param subscriber moves out of PageZoomFeature into its own TrackingParamsFeature next to SettingsSyncFeature. - Docs: LOTUS_FEATURES entries for #103/#104; LOTUS_TODO links the new Features 2026-Q4 milestone and #108. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
@@ -21,6 +21,7 @@ import { NOTIFICATION_SOUND_MAP } from '../../utils/notificationSounds';
|
||||
import { useSetting } from '../../state/hooks/settings';
|
||||
import { settingsAtom } from '../../state/settings';
|
||||
import { setStripTrackingOnRender } from '../../plugins/react-custom-html-parser';
|
||||
import { useSettingsSync } from '../../hooks/useSettingsSync';
|
||||
import { allInvitesAtom } from '../../state/room-list/inviteList';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { useHydrateMsgDrafts } from '../../hooks/useHydrateMsgDrafts';
|
||||
@@ -89,13 +90,23 @@ function SystemEmojiFeature() {
|
||||
return null;
|
||||
}
|
||||
|
||||
function PageZoomFeature() {
|
||||
const [pageZoom] = useSetting(settingsAtom, 'pageZoom');
|
||||
// [Gitea #103] Mirror the privacy toggle into the html parser's module flag.
|
||||
// [Gitea #103] Mirror the privacy toggle into the html parser's module flag.
|
||||
function TrackingParamsFeature() {
|
||||
const [stripTracking] = useSetting(settingsAtom, 'stripTrackingParams');
|
||||
useEffect(() => {
|
||||
setStripTrackingOnRender(stripTracking);
|
||||
}, [stripTracking]);
|
||||
return null;
|
||||
}
|
||||
|
||||
// [Gitea #104] Mirror user preferences to account data and apply remote snapshots.
|
||||
function SettingsSyncFeature() {
|
||||
useSettingsSync();
|
||||
return null;
|
||||
}
|
||||
|
||||
function PageZoomFeature() {
|
||||
const [pageZoom] = useSetting(settingsAtom, 'pageZoom');
|
||||
|
||||
if (pageZoom === 100) {
|
||||
document.documentElement.style.removeProperty('font-size');
|
||||
@@ -893,6 +904,8 @@ export function ClientNonUIFeatures({ children }: ClientNonUIFeaturesProps) {
|
||||
<SearchCacheInvalidationFeature />
|
||||
<SystemEmojiFeature />
|
||||
<PageZoomFeature />
|
||||
<TrackingParamsFeature />
|
||||
<SettingsSyncFeature />
|
||||
<FaviconUpdater />
|
||||
<PresenceUpdater />
|
||||
<MuteTimerRestore />
|
||||
|
||||
Reference in New Issue
Block a user