fix(plex): optimistic toggle + 'importing' indicator for watch-sync
The watch-sync switch only flipped once the (multi-second) import request returned, so a click read as 'nothing happened' and invited repeat clicks. Reflect the toggle's target optimistically while the mutation is in flight and show an 'Importing your Plex watch history…' spinner line, so it's obvious the switch responded and is working.
This commit is contained in:
parent
cbe203391e
commit
02837b9a4b
4 changed files with 32 additions and 19 deletions
|
|
@ -461,6 +461,10 @@ function PlexWatchSync() {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const busy = toggle.isPending || reimport.isPending;
|
||||||
|
// Reflect the toggle's target immediately (optimistic) so the switch responds on click rather than
|
||||||
|
// only flipping once the multi-second import returns — otherwise it reads as "nothing happened".
|
||||||
|
const shown = toggle.isPending ? Boolean(toggle.variables) : enabled;
|
||||||
const last = link.data?.last_watch_sync_at
|
const last = link.data?.last_watch_sync_at
|
||||||
? new Date(link.data.last_watch_sync_at).toLocaleString(i18n.language)
|
? new Date(link.data.last_watch_sync_at).toLocaleString(i18n.language)
|
||||||
: null;
|
: null;
|
||||||
|
|
@ -470,25 +474,31 @@ function PlexWatchSync() {
|
||||||
<p className="text-xs text-muted leading-relaxed mb-2">{t("settings.plexSync.intro")}</p>
|
<p className="text-xs text-muted leading-relaxed mb-2">{t("settings.plexSync.intro")}</p>
|
||||||
<SettingRow label={t("settings.plexSync.toggle")} hint={t("settings.plexSync.toggleHint")}>
|
<SettingRow label={t("settings.plexSync.toggle")} hint={t("settings.plexSync.toggleHint")}>
|
||||||
<Switch
|
<Switch
|
||||||
checked={enabled}
|
checked={shown}
|
||||||
disabled={toggle.isPending || reimport.isPending}
|
disabled={busy}
|
||||||
onChange={(v) => !toggle.isPending && toggle.mutate(v)}
|
onChange={(v) => !busy && toggle.mutate(v)}
|
||||||
/>
|
/>
|
||||||
</SettingRow>
|
</SettingRow>
|
||||||
{enabled && (
|
{busy ? (
|
||||||
|
<div className="mt-2 flex items-center gap-2 text-xs text-muted">
|
||||||
|
<RefreshCw className="w-3.5 h-3.5 animate-spin" />
|
||||||
|
{t("settings.plexSync.importing")}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
enabled && (
|
||||||
<div className="mt-2 flex items-center justify-between gap-3">
|
<div className="mt-2 flex items-center justify-between gap-3">
|
||||||
<p className="text-xs text-muted">
|
<p className="text-xs text-muted">
|
||||||
{last ? t("settings.plexSync.lastSync", { when: last }) : t("settings.plexSync.never")}
|
{last ? t("settings.plexSync.lastSync", { when: last }) : t("settings.plexSync.never")}
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
onClick={() => reimport.mutate()}
|
onClick={() => reimport.mutate()}
|
||||||
disabled={reimport.isPending}
|
className="inline-flex items-center gap-1.5 px-3 py-2 rounded-xl text-sm border border-border hover:bg-card/60 transition shrink-0"
|
||||||
className="inline-flex items-center gap-1.5 px-3 py-2 rounded-xl text-sm border border-border hover:bg-card/60 disabled:opacity-50 transition shrink-0"
|
|
||||||
>
|
>
|
||||||
<RefreshCw className={`w-4 h-4 ${reimport.isPending ? "animate-spin" : ""}`} />
|
<RefreshCw className="w-4 h-4" />
|
||||||
{t("settings.plexSync.importNow")}
|
{t("settings.plexSync.importNow")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
)
|
||||||
)}
|
)}
|
||||||
</Section>
|
</Section>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@
|
||||||
"importNow": "Jetzt aus Plex importieren",
|
"importNow": "Jetzt aus Plex importieren",
|
||||||
"imported": "Aus Plex importiert: {{watched}} gesehen, {{in_progress}} laufend.",
|
"imported": "Aus Plex importiert: {{watched}} gesehen, {{in_progress}} laufend.",
|
||||||
"lastSync": "Letzter Import: {{when}}",
|
"lastSync": "Letzter Import: {{when}}",
|
||||||
"never": "Noch nicht importiert"
|
"never": "Noch nicht importiert",
|
||||||
|
"importing": "Plex-Wiedergabeverlauf wird importiert…"
|
||||||
},
|
},
|
||||||
"save": {
|
"save": {
|
||||||
"unsaved": "Nicht gespeicherte Änderungen",
|
"unsaved": "Nicht gespeicherte Änderungen",
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@
|
||||||
"importNow": "Import from Plex now",
|
"importNow": "Import from Plex now",
|
||||||
"imported": "Imported from Plex: {{watched}} watched, {{in_progress}} in progress.",
|
"imported": "Imported from Plex: {{watched}} watched, {{in_progress}} in progress.",
|
||||||
"lastSync": "Last import: {{when}}",
|
"lastSync": "Last import: {{when}}",
|
||||||
"never": "Not imported yet"
|
"never": "Not imported yet",
|
||||||
|
"importing": "Importing your Plex watch history…"
|
||||||
},
|
},
|
||||||
"save": {
|
"save": {
|
||||||
"unsaved": "Unsaved changes",
|
"unsaved": "Unsaved changes",
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@
|
||||||
"importNow": "Importálás a Plexből most",
|
"importNow": "Importálás a Plexből most",
|
||||||
"imported": "Importálva a Plexből: {{watched}} megnézve, {{in_progress}} folyamatban.",
|
"imported": "Importálva a Plexből: {{watched}} megnézve, {{in_progress}} folyamatban.",
|
||||||
"lastSync": "Utolsó import: {{when}}",
|
"lastSync": "Utolsó import: {{when}}",
|
||||||
"never": "Még nincs importálva"
|
"never": "Még nincs importálva",
|
||||||
|
"importing": "Plex-előzmény importálása…"
|
||||||
},
|
},
|
||||||
"save": {
|
"save": {
|
||||||
"unsaved": "Nem mentett változások",
|
"unsaved": "Nem mentett változások",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue