feat(design): the Copy rule — names, verbs, dates and units (E28 S3g)

The owner's picks (all the recommended options) become DESIGN.md's Copy
chapter and a sweep of both languages (742 values, no key drift):

- One name per feature: the rail's label, which may shorten it (Alerts
  -> Notifications, Fiókok -> Felhasználók, Download Center -> Downloads,
  Channel manager -> Channels); one "sync from YouTube" verb.
- Four verbs, four meanings (Delete / Remove / Dismiss / Discard, and
  their Hungarian pairs), checked against what each action does.
- Sentence case, the app's places capitalised; "…" on a command that
  asks first (a popover or form title got its own key without it);
  one-sentence messages without a stop or a tick, "Couldn't …"; curly
  quotes.
- Dates only from lib/format.ts, in the UI language: formatDateTime
  names the month and stops at the minute (it printed "9/27/2026,
  8:30:14 AM"), formatDateTimeSec for the log, the audit and the
  recorder; ui/RelativeTime pairs "3d ago" with the exact minute on
  hover. local/date-format refuses toLocale*String and Intl date
  formatters elsewhere.
- Units from Intl, short (formatUnit): runtimes, totals, the Scheduler
  countdown, the stats range, the player's tap skip. "2h 13m" was
  English in both languages.
- src/i18n/copyRule.test.ts holds the machine-readable part (quotes,
  "...", ticks, bare unit letters).
This commit is contained in:
2026-09-27 05:46:17 +02:00
parent 2c65edfffd
commit bd6aaa1e43
100 changed files with 1193 additions and 964 deletions
+34 -33
View File
@@ -5,11 +5,11 @@
"playAll": "Play all",
"shuffle": "Shuffle",
"rename": "Rename",
"addItem": "Add title",
"addItem": "Add title…",
"delete": "Delete",
"enableEdit": "Enable editing",
"removeItem": "Remove from collection",
"removeConfirm": "Remove \"{{title}}\" from this collection? This affects all users on Plex.",
"removeConfirm": "Remove “{{title}}” from this collection? This affects all users on Plex.",
"nameMaybeTaken": "A collection with this name may already exist in another library — you can still create it here.",
"readOnly": "Read-only",
"empty": "This collection has no items.",
@@ -20,16 +20,17 @@
"addNoResults": "No matches.",
"add": "Add",
"added": "Added",
"deleteConfirm": "Delete the collection \"{{title}}\"? This removes it from Plex too.",
"editFailed": "Collection edit failed",
"playFailed": "Couldn't build the play queue — try again.",
"playEmpty": "Nothing to play in this collection yet.",
"newCollection": "New collection",
"deleteConfirm": "Delete the collection “{{title}}”? This removes it from Plex too.",
"editFailed": "Couldn't edit the collection",
"playFailed": "Couldn't build the play queue — try again",
"playEmpty": "Nothing to play in this collection yet",
"newCollection": "New collection…",
"newCollectionTitle": "New collection",
"namePlaceholder": "Collection name",
"nameTaken": "A collection with this name already exists.",
"nameTaken": "A collection with this name already exists",
"newHint": "Pick the first title to add — a collection needs at least one.",
"createWith": "Create",
"deleteFailed": "Couldn't delete the collection."
"deleteFailed": "Couldn't delete the collection"
},
"searchPlaceholder": "Search Plex…",
"searchField": {
@@ -78,13 +79,13 @@
"duration": "Length",
"durationUnit": "min",
"durationOpt": {
"short": "Under 90m",
"mid": "90–120m",
"long": "Over 2h"
"short": "Under 90 min",
"mid": "90–120 min",
"long": "Over 2 hr"
},
"added": "Added to Plex",
"addedOpt": {
"24h": "24h",
"24h": "24 hours",
"1w": "1 week",
"1m": "1 month",
"6m": "6 months",
@@ -128,7 +129,7 @@
"markNextWatched": "Mark S{{season}}·E{{episode}} watched",
"markNextUnwatched": "Mark S{{season}}·E{{episode}} unwatched",
"nextUp": "Next: S{{season}}·E{{episode}}",
"watchedFailed": "Couldn't update the watched state — please try again.",
"watchedFailed": "Couldn't update the watched state — please try again",
"seasons": "{{count}} seasons",
"unified": {
"titles": "Titles",
@@ -157,9 +158,9 @@
"none": "No editable collections yet. Create one above.",
"count": "{{count}} items",
"delete": "Delete",
"deleteConfirm": "Delete the collection \"{{title}}\" from Plex? This affects all users.",
"deleteConfirm": "Delete the collection “{{title}}” from Plex? This affects all users.",
"note": "Changes are written to Plex and shared across all clients and users.",
"others": "Manage {{count}} existing collections…",
"others": "Manage {{count}} existing collections",
"makeEditable": "Manage"
},
"player": {
@@ -174,8 +175,8 @@
"restart": "Restart from beginning",
"prev": "Previous episode",
"next": "Next episode",
"tapBack": "−{{n}} s",
"tapForward": "+{{n}} s",
"tapBack": "−{{d}}",
"tapForward": "+{{d}}",
"mute": "Mute (m)",
"volume": "Volume",
"fullscreen": "Fullscreen (f)",
@@ -222,9 +223,9 @@
"subStyle": "Subtitles",
"subPreparing": "Preparing subtitles: {{label}}…",
"subUnavailable": {
"bitmap": "This subtitle is image-based and can't be shown as text.",
"missing": "This subtitle track isn't available.",
"failed": "This subtitle couldn't be loaded."
"bitmap": "This subtitle is image-based and can't be shown as text",
"missing": "This subtitle track isn't available",
"failed": "Couldn't load this subtitle"
},
"subSize": "Text size",
"subPos": "Position",
@@ -274,7 +275,7 @@
"audience": "Audience",
"keywords": "Keywords",
"crew": "Crew",
"filterValue": "Filter by \"{{name}}\"",
"filterValue": "Filter by “{{name}}”",
"facts": {
"title": "Details",
"release": "Released",
@@ -294,23 +295,23 @@
"transcode_sw": "Transcoded in software (heaviest)"
},
"playlistAdd": {
"manage": "Add to playlist",
"manage": "Add to playlist…",
"title": "Add to playlist — {{title}}",
"newPlaceholder": "New playlist name…",
"create": "Create",
"none": "No playlists yet. Create one above.",
"count": "{{count}} items",
"groupProgress": "{{in}} / {{size}}",
"addFailed": "Couldn't add it to the playlist.",
"removeFailed": "Couldn't remove it from the playlist.",
"createFailed": "Couldn't create the playlist."
"addFailed": "Couldn't add it to the playlist",
"removeFailed": "Couldn't remove it from the playlist",
"createFailed": "Couldn't create the playlist"
},
"playlist": {
"section": "Playlists",
"pickerPlaceholder": "Find or create a playlist…",
"createNamed": "Create \"{{name}}\"",
"createNamed": "Create “{{name}}”",
"none": "No playlists yet.",
"deleteConfirm": "Delete the playlist \"{{title}}\"?",
"deleteConfirm": "Delete the playlist “{{title}}”?",
"rename": "Rename",
"playAll": "Play all",
"delete": "Delete playlist",
@@ -326,10 +327,10 @@
"addShow": "Add whole show to a playlist",
"addSeason": "Add season 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.",
"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",
"reorderItem": "Move “{{title}}”",
"rowMenu": "Item actions",
"menu": "Playlist actions",
@@ -337,7 +338,7 @@
"playSeason": "Play the season",
"removeFromPlaylist": "Remove from the playlist",
"removedToast": "“{{title}}” removed from the playlist",
"undoRemoveFailed": "Couldn't put it back in the playlist."
"undoRemoveFailed": "Couldn't put it back in the playlist"
},
"people": {
"count_one": "{{count}} title",