Files
siftlode/frontend/src/i18n/locales/en/playlists.json
T
peter 267fd7f70f 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.
2026-09-11 23:34:33 +02:00

130 lines
6.6 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"title": "Playlists",
"manageGroup": "Manage",
"listGroup": "Your playlists",
"watchLater": "Watch later",
"syncYoutube": "Sync from YouTube",
"syncedToast": "Synced {{count}} playlists from YouTube",
"syncFailed": "Couldn't sync from YouTube",
"ytReadonly": "Synced from YouTube — edits sync back",
"noneYet": "No playlists yet",
"newPlaylist": "New playlist…",
"searchPlaceholder": "Search playlists…",
"noMatches": "No playlists match.",
"itemCount_one": "{{count}} video",
"itemCount_other": "{{count}} videos",
"pickOne": "Pick a playlist on the left.",
"loading": "Loading…",
"empty": "This playlist is empty — add videos from the feed.",
"playAll": "Play all",
"delete": "Delete",
"rename": "Rename",
"confirmDelete": "Delete the playlist “{{name}}”? This can't be undone.",
"addToPlaylist": "Add to playlist",
"exportToYoutube": "Export to YouTube",
"pushToYoutube": "Sync to YouTube",
"unsynced": "Unsynced",
"unsyncedHint": "You have local changes not yet synced to YouTube.",
"openOnYoutube": "Open on YouTube",
"revert": "Reset to YouTube",
"revertTitle": "Discard local changes?",
"revertMsg": "This reloads the playlist from YouTube and discards your unsynced local changes (order, additions, removals, rename). Continue?",
"revertConfirm": "Discard & reload",
"revertDone": "“{{name}}” reloaded from YouTube ✓",
"revertFailed": "Couldn't reload from YouTube.",
"pushTitle": "Sync to YouTube",
"pushConfirm": "Sync",
"pushPlanCreate": "Create a new YouTube playlist with {{count}} videos? (~{{units}} quota units; {{left}} left today.)",
"mergeAddLocal_one": "{{count}} video added to Siftlode from YouTube.",
"mergeAddLocal_other": "{{count}} videos added to Siftlode from YouTube.",
"mergeRemoveLocal_one": "{{count}} video removed from Siftlode.",
"mergeRemoveLocal_other": "{{count}} videos removed from Siftlode.",
"mergeAddYt_one": "{{count}} video added to YouTube.",
"mergeAddYt_other": "{{count}} videos added to YouTube.",
"mergeRemoveYt_one": "{{count}} video removed from YouTube.",
"mergeRemoveYt_other": "{{count}} videos removed from YouTube.",
"mergeReorder_one": "{{count}} video reordered on YouTube.",
"mergeReorder_other": "{{count}} videos reordered on YouTube.",
"mergeRename": "The playlist will be renamed on YouTube.",
"mergeYtUnchanged": "Your YouTube playlist stays unchanged.",
"mergeLocalUnchanged": "Your Siftlode playlist stays unchanged.",
"mergeQuota": " (~{{units}} quota units; {{left}} left today.)",
"mergeQuotaFree": " (~0 quota units.)",
"pushNoQuota": "Not enough YouTube quota left today ({{left}}) for this sync (~{{units}} needed). Try again tomorrow.",
"pushUpToDate": "“{{name}}” is already in sync with YouTube.",
"pushDone": "“{{name}}” synced to YouTube ✓",
"pushPartial": "Synced, but {{count}} item(s) were skipped.",
"pushFailed": "Couldn't sync to YouTube.",
"deleteHereOnly": "Delete here only",
"deleteYtFailed": "Couldn't delete on YouTube; removed here only.",
"sortLabel": "Sort",
"dirAsc": "Ascending",
"dirDesc": "Descending",
"groupByChannel": "Group by channel",
"railSortCustom": "Custom order",
"railSortName": "Name",
"railSortCount": "Item count",
"railSortDuration": "Total length",
"railSortRecent": "Recently changed",
"dirtyFirst": "Unsynced first",
"colTitle": "Title",
"colChannel": "Channel",
"colDuration": "Length",
"rowMenu": "Video actions",
"moveTo": "Move to another list",
"moveToRecent": "Move to “{{name}}”",
"moveNoTargets": "There is no other playlist to move it to yet.",
"movedToast": "“{{title}}” moved to “{{name}}” ✓",
"moveFailed": "Couldn't move the video.",
"removeFailed": "Couldn't remove the video.",
"errors": {
"name_required": "Give the playlist a name.",
"youtube_read_scope": "Connect YouTube (read access) to sync your playlists.",
"not_on_youtube": "This playlist isn't on YouTube.",
"youtube_failed": "YouTube didn't accept that just now. Please try again.",
"watch_later_not_pushable": "The Watch later list can't be sent to YouTube.",
"watch_later_undeletable": "The Watch later list can't be deleted.",
"youtube_editing_off": "Enable YouTube editing in Settings first.",
"quota_exceeded": "Not enough YouTube quota left today for this sync."
},
"moveErrors": {
"not_in_playlist": "That video isn't in this playlist any more — it changed somewhere else.",
"same_playlist": "That video is already in this playlist."
},
"orderTop": "Move to top",
"orderUp": "Move up",
"orderDown": "Move down",
"orderBottom": "Move to bottom",
"railMenu": "Playlist actions",
"builtinLocked": "The built-in {{name}} list can’t be renamed or deleted.",
"removeItem": "Remove",
"removeItemOf": "Remove “{{title}}” from the playlist",
"confirmRemove": "Remove “{{title}}” from this playlist?",
"dragHandle": "Drag to reorder",
"dragHandleOf": "Reorder “{{title}}”",
"dragBlockedSort": "Reordering by hand is off while a column sort or grouping is applied.",
"dragBlockedFilter": "Reordering by hand is off while a filter is applied.",
"clearView": "Reset view",
"saveOrder": "Save this order",
"filteredCount": "{{count}} shown",
"noneMatchFilter": "No videos match the filter.",
"loadFailed": "Couldn't load this playlist.",
"reorderFailed": "Couldn't save the new order.",
"renameFailed": "Couldn't rename the playlist.",
"deleteFailed": "Couldn't delete the playlist.",
"confirmDeleteLinked": "Delete the playlist “{{name}}”? It is synced with YouTube — choose whether to delete it there as well. This can't be undone.",
"dragBlockedBuiltin": "This list's order is fixed — it can't be reordered by hand.",
"deleteBoth": "Delete here and on YouTube",
"dndInstructions": "Press space to pick up a video, the arrow keys to move it, space again to drop it, or escape to cancel.",
"dndPickedUp": "Picked up “{{title}}”, position {{pos}} of {{total}}.",
"dndMovedOver": "“{{title}}” moved to position {{pos}} of {{total}}.",
"dndDropped": "“{{title}}” dropped at position {{pos}} of {{total}}.",
"dndCancelled": "Move cancelled; “{{title}}” is back at position {{pos}}.",
"viewGrouped": "grouped by channel",
"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.",
"addFailed": "Couldn't add it to the playlist."
}