feat(settings): explicit Save/Discard for preferences with dirty tracking

Settings-page prefs (theme/scheme/dark-mode/list-view/perf/hints/font + the
notification settings) were each auto-saved to the server on every toggle via
fire-and-forget savePrefs().catch(() => {}) — silent on failure, and no
positive confirmation on success, so the user had zero feedback either way.

Make them a draft instead: changes apply locally for instant preview but
persist only on an explicit Save (or revert on Discard). App owns the live
draft + the last-saved baseline, computes dirty, and exposes a controller to
the panel. The panel shows a Save/Discard bar with 'Saving…' → 'Settings
saved' (auto-clearing) / 'Couldn't save' feedback. Leaving the page with
unsaved changes prompts a confirm (in-app nav + browser Back), and a
beforeunload guards reload/close. savePrefs is now idempotent so the Save
survives a transient gateway blip; failures surface via the connection-lost
status. Language & sidebar layout stay instant (edited outside this page).

New i18n keys settings.save.* / settings.unsaved.* in EN/HU/DE.
This commit is contained in:
npeter83 2026-06-18 23:59:40 +02:00
parent c0192b8bb7
commit d24ff9c0f0
6 changed files with 336 additions and 120 deletions

View file

@ -6,6 +6,19 @@
"sync": "Synchronisierung",
"account": "Konto"
},
"save": {
"unsaved": "Nicht gespeicherte Änderungen",
"saving": "Speichern…",
"saved": "Einstellungen gespeichert",
"failed": "Speichern fehlgeschlagen",
"save": "Speichern",
"discard": "Verwerfen"
},
"unsaved": {
"title": "Nicht gespeicherte Änderungen",
"message": "Du hast nicht gespeicherte Einstellungen. Verwerfen und verlassen?",
"discard": "Änderungen verwerfen"
},
"appearance": {
"colorScheme": "Farbschema",
"display": "Anzeige",

View file

@ -6,6 +6,19 @@
"sync": "Sync",
"account": "Account"
},
"save": {
"unsaved": "Unsaved changes",
"saving": "Saving…",
"saved": "Settings saved",
"failed": "Couldn't save",
"save": "Save",
"discard": "Discard"
},
"unsaved": {
"title": "Unsaved changes",
"message": "You have unsaved settings. Discard them and leave?",
"discard": "Discard changes"
},
"appearance": {
"colorScheme": "Color scheme",
"display": "Display",

View file

@ -6,6 +6,19 @@
"sync": "Szinkronizálás",
"account": "Fiók"
},
"save": {
"unsaved": "Nem mentett változások",
"saving": "Mentés…",
"saved": "Beállítások elmentve",
"failed": "Nem sikerült menteni",
"save": "Mentés",
"discard": "Elvetés"
},
"unsaved": {
"title": "Nem mentett változások",
"message": "Vannak nem mentett beállításaid. Elveted őket és továbblépsz?",
"discard": "Változások elvetése"
},
"appearance": {
"colorScheme": "Színséma",
"display": "Megjelenítés",