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
|
||||
? new Date(link.data.last_watch_sync_at).toLocaleString(i18n.language)
|
||||
: null;
|
||||
|
|
@ -470,25 +474,31 @@ function PlexWatchSync() {
|
|||
<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")}>
|
||||
<Switch
|
||||
checked={enabled}
|
||||
disabled={toggle.isPending || reimport.isPending}
|
||||
onChange={(v) => !toggle.isPending && toggle.mutate(v)}
|
||||
checked={shown}
|
||||
disabled={busy}
|
||||
onChange={(v) => !busy && toggle.mutate(v)}
|
||||
/>
|
||||
</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">
|
||||
<p className="text-xs text-muted">
|
||||
{last ? t("settings.plexSync.lastSync", { when: last }) : t("settings.plexSync.never")}
|
||||
</p>
|
||||
<button
|
||||
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 disabled:opacity-50 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 transition shrink-0"
|
||||
>
|
||||
<RefreshCw className={`w-4 h-4 ${reimport.isPending ? "animate-spin" : ""}`} />
|
||||
<RefreshCw className="w-4 h-4" />
|
||||
{t("settings.plexSync.importNow")}
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@
|
|||
"importNow": "Jetzt aus Plex importieren",
|
||||
"imported": "Aus Plex importiert: {{watched}} gesehen, {{in_progress}} laufend.",
|
||||
"lastSync": "Letzter Import: {{when}}",
|
||||
"never": "Noch nicht importiert"
|
||||
"never": "Noch nicht importiert",
|
||||
"importing": "Plex-Wiedergabeverlauf wird importiert…"
|
||||
},
|
||||
"save": {
|
||||
"unsaved": "Nicht gespeicherte Änderungen",
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@
|
|||
"importNow": "Import from Plex now",
|
||||
"imported": "Imported from Plex: {{watched}} watched, {{in_progress}} in progress.",
|
||||
"lastSync": "Last import: {{when}}",
|
||||
"never": "Not imported yet"
|
||||
"never": "Not imported yet",
|
||||
"importing": "Importing your Plex watch history…"
|
||||
},
|
||||
"save": {
|
||||
"unsaved": "Unsaved changes",
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@
|
|||
"importNow": "Importálás a Plexből most",
|
||||
"imported": "Importálva a Plexből: {{watched}} megnézve, {{in_progress}} folyamatban.",
|
||||
"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": {
|
||||
"unsaved": "Nem mentett változások",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue