fix(settings): case sync asks and merges only while it is on

- session-ui.js: no GET /api/settings on a tab return unless this device's cached syncCaseState is true
- system-routes.ts: caseSettings is merged only while syncCaseState is true (as stored or set by the same PUT)
- sync-case-state tests cover both; wiki notes the stored options stay when sync is turned off
This commit is contained in:
Devvyn committed 2026-11-09 10:03:08 +08:00
1 parent a50d0db283
commit f8ff431d30
5 files changed
+24 -6

No files matched your search

+3
View File
@@ -3759,6 +3759,9 @@ Object.assign(CodemanApp.prototype, {
/** On returning to the tab: take the other devices' case options and selected case, if the server has sync on. */
async _syncCaseStateFromServer() {
if (this._settingsReadOnly?.()) return;
// Off on this device: no request on every tab return. Turning it on elsewhere is learned from the
// next settings load; turning it off elsewhere still reaches a device whose cached switch is on.
if (this.loadAppSettingsFromStorage().syncCaseState !== true) return;
const seq = (this._caseSyncRefresh = (this._caseSyncRefresh || 0) + 1);
try {
await this._caseSyncChain; // this device's own saves land first, so the copy read next includes them
+5 -1
View File
@@ -1145,10 +1145,14 @@ export function registerSystemRoutes(
if (settings.tunnelEnabled === true && !tunnelEnableAuthorized) delete settingsToStore.tunnelEnabled;
// caseSettings merges per case inside the serialised writer, so two devices saving different cases both land.
const { caseSettings: incomingCases, ...plainSettings } = settingsToStore;
// The map is read and written only while syncCaseState is on, so a PUT that carries it with the setting off
// (as stored, or as this same PUT sets it) leaves the stored map alone.
const { before: existing, after } = await mutateSettingsFile((current) => ({
...current,
...plainSettings,
...(incomingCases ? { caseSettings: mergeCaseSettings(current.caseSettings, incomingCases as never) } : {}),
...(incomingCases && (plainSettings.syncCaseState ?? current.syncCaseState) === true
? { caseSettings: mergeCaseSettings(current.caseSettings, incomingCases as never) }
: {}),
}));
const merged = after ?? { ...existing, ...plainSettings };