fix(playlists): a refused edit is taken back on screen, and a gone list or tag is said, not swallowed

Deep-review round 4, the playlist surfaces.

- A failed move or reorder relied on the resync to put the rows back — but the server's list is
  unchanged, so the refetch comes back deep-equal, react-query keeps the same `data` object, and the
  re-seed effect keyed on it never ran: the moved row stayed gone, the rejected order stayed on
  screen. Both restore from the cached detail now.
- A failed removal puts its row back itself: when the server is unreachable the resync fails too,
  and round 3's "keep the list on a failed refetch" guard then kept showing it as removed.
- The Plex playlist page (remove / rename / delete / reorder), the add-to-playlist popover and the
  tag manager had no failure handling at all: a list or tag deleted elsewhere (a 404, now a
  structured `not_found` the request layer leaves to the caller) failed in silence and an
  optimistic removal stayed removed. Each says it and resyncs; deleting a Plex playlist that is
  already gone just leaves the page.
- Playlists' own loading/error branches use the shared `LoadingState` / `StateMessage` (the loading
  line had no live region).
- The "player stays mounted" tests count mounts: a remount ended with the same flag as staying up.
This commit is contained in:
2026-09-11 23:34:33 +02:00
parent 6d49da17fe
commit 267fd7f70f
12 changed files with 309 additions and 37 deletions
+2 -1
View File
@@ -124,5 +124,6 @@
"viewGroupedAnd": "grouped by channel, {{sort}}",
"viewDiffers": "Temporary view ({{view}}) — the playlist's saved order is unchanged. Save it to keep this order.",
"viewMatches": "This view ({{view}}) already matches the playlist's saved order, so there is nothing to save.",
"viewFiltered": "Filtered view — {{shown}} of {{total}} shown. The order can't be saved while a filter is on."
"viewFiltered": "Filtered view — {{shown}} of {{total}} shown. The order can't be saved while a filter is on.",
"addFailed": "Couldn't add it to the playlist."
}
+5 -1
View File
@@ -320,7 +320,11 @@
"seasonUnknown": "Episodes",
"addShow": "Add whole show to a playlist",
"addSeason": "Add season to a playlist",
"addEpisode": "Add episode to a playlist"
"addEpisode": "Add episode to a playlist",
"removeFailed": "Couldn't remove it from the playlist.",
"renameFailed": "Couldn't rename the playlist.",
"deleteFailed": "Couldn't delete the playlist.",
"reorderFailed": "Couldn't save the new order."
},
"people": {
"count_one": "{{count}} title",
+3 -1
View File
@@ -8,5 +8,7 @@
"confirmDelete": "Delete the tag “{{name}}”? It will be removed from every channel it's on.",
"empty": "No tags yet — add one below.",
"newPlaceholder": "New tag name…",
"add": "Add"
"add": "Add",
"renameFailed": "Couldn't rename the tag.",
"deleteFailed": "Couldn't delete the tag."
}
+2 -1
View File
@@ -124,5 +124,6 @@
"viewGroupedAnd": "csatorna szerint csoportosítva, {{sort}}",
"viewDiffers": "Ideiglenes nézet ({{view}}) — a lista mentett sorrendje változatlan. Mentsd, ha ez maradjon.",
"viewMatches": "Ez a nézet ({{view}}) megegyezik a lista mentett sorrendjével, így nincs mit menteni.",
"viewFiltered": "Szűrt nézet — {{total}} elemből {{shown}} látszik. Szűrés közben a sorrend nem menthető."
"viewFiltered": "Szűrt nézet — {{total}} elemből {{shown}} látszik. Szűrés közben a sorrend nem menthető.",
"addFailed": "Nem sikerült hozzáadni a lejátszási listához."
}
+5 -1
View File
@@ -320,7 +320,11 @@
"seasonUnknown": "Epizódok",
"addShow": "Egész sorozat listához adása",
"addSeason": "Évad listához adása",
"addEpisode": "Epizód listához adása"
"addEpisode": "Epizód listához adása",
"removeFailed": "Nem sikerült eltávolítani a lejátszási listáról.",
"renameFailed": "Nem sikerült átnevezni a lejátszási listát.",
"deleteFailed": "Nem sikerült törölni a lejátszási listát.",
"reorderFailed": "Nem sikerült menteni az új sorrendet."
},
"people": {
"count_one": "{{count}} cím",
+3 -1
View File
@@ -8,5 +8,7 @@
"confirmDelete": "Törlöd a(z) „{{name}}” címkét? Minden csatornáról lekerül, amin rajta van.",
"empty": "Még nincs címke — adj hozzá lentebb.",
"newPlaceholder": "Új címke neve…",
"add": "Hozzáad"
"add": "Hozzáad",
"renameFailed": "Nem sikerült átnevezni a címkét.",
"deleteFailed": "Nem sikerült törölni a címkét."
}