feat(ux): R11 feedback symmetry — Plex/download/rollback/deny notices

Give equal-weight actions equal-weight feedback (R11).

S1 Plex error toasts: the watched-toggles (card / season mark-all / episode /
info-panel / show mark-all) used to fail silently on 403/404/429; each now surfaces
the server reason via a shared notifyActionError() + resyncs the optimistic flip.
The playback auto-mark-watched stays intentionally silent (a mid-play toast is
noise; the next sync corrects it). New generic lib/actionErrors.ts (Plex + saved
views reuse it; notifyYouTubeActionError delegates its non-403 case to it).

S2 download-done inbox notification: worker.py emits a best-effort type=download_done
notice to the job owner on real completion (regular + edit jobs, not instant
cache-hits), rendered/localized in the inbox with an Open-Downloads link.

S3 optimistic rollbacks: SavedViewsWidget create/rename/toggle-default/remove/reorder
and the inbox revert-state no longer swallow failures — they toast + refetch to
resync (the reorder's optimistic order reverts to server truth).

S4 access-request deny: deny_invite now emails the requester (send_access_denied),
mirroring approve — no more silent limbo.
This commit is contained in:
2026-08-11 05:05:50 +02:00
parent 354b3dd10c
commit e2fe6fa286
15 changed files with 154 additions and 14 deletions
+5
View File
@@ -12,6 +12,11 @@
"sectionActivity": "Activity",
"andMore": "and {{count}} more",
"openScheduler": "Open Scheduler",
"openDownloads": "Open Downloads",
"revertFailed": "Couldn't undo that — please try again.",
"downloadDone": {
"title": "Download ready"
},
"maintenance": {
"title": "Videos removed",
"body_one": "{{count}} saved or playlisted video was removed because it's no longer available on YouTube.",
+1
View File
@@ -74,6 +74,7 @@
"openShow": "Open show",
"markWatched": "Mark watched",
"markUnwatched": "Mark unwatched",
"watchedFailed": "Couldn't update the watched state — please try again.",
"seasons": "{{count}} seasons",
"unified": {
"titles": "Titles",
+3 -1
View File
@@ -12,5 +12,7 @@
"rename": "Rename",
"delete": "Delete",
"deleteConfirm": "Delete the saved view “{{name}}”?",
"reorder": "Drag to reorder"
"reorder": "Drag to reorder",
"actionFailed": "Couldn't update your saved views — please try again.",
"reorderFailed": "Couldn't save the new order — please try again."
}
+5
View File
@@ -12,6 +12,11 @@
"sectionActivity": "Tevékenység",
"andMore": "és még {{count}}",
"openScheduler": "Ütemező megnyitása",
"openDownloads": "Letöltések megnyitása",
"revertFailed": "Nem sikerült visszavonni — próbáld újra.",
"downloadDone": {
"title": "Letöltés kész"
},
"maintenance": {
"title": "Videók eltávolítva",
"body_one": "{{count}} mentett vagy lejátszási listás videó eltávolítva, mert már nem elérhető a YouTube-on.",
+1
View File
@@ -74,6 +74,7 @@
"openShow": "Sorozat megnyitása",
"markWatched": "Megnézettnek jelöl",
"markUnwatched": "Nem-nézettnek jelöl",
"watchedFailed": "Nem sikerült frissíteni a megnézett állapotot — próbáld újra.",
"seasons": "{{count}} évad",
"unified": {
"titles": "Címek",
+3 -1
View File
@@ -12,5 +12,7 @@
"rename": "Átnevezés",
"delete": "Törlés",
"deleteConfirm": "Törlöd a(z) „{{name}}” mentett nézetet?",
"reorder": "Húzd az átrendezéshez"
"reorder": "Húzd az átrendezéshez",
"actionFailed": "Nem sikerült frissíteni a mentett nézeteket — próbáld újra.",
"reorderFailed": "Nem sikerült menteni az új sorrendet — próbáld újra."
}