fix(i18n): every counted string is a plural pair, so one reads singular
"1 seasons", "Synced 1 subscriptions", "1 video(s) were skipped": 21 English
strings carried {{count}} in one plain key and read plural at one. Each is a
_one/_other pair now (Hungarian keeps one form for both), and so is every other
counted string, so the next wording change is a plural too. A contract test
holds the rule for every locale file.
This commit is contained in:
@@ -6,7 +6,8 @@
|
||||
"clear": "Clear audit log",
|
||||
"clearTitle": "Clear the audit log?",
|
||||
"clearConfirm": "Permanently delete all audit entries? This can't be undone. (One entry recording that you cleared it is kept.)",
|
||||
"cleared": "Cleared {{count}} audit entries",
|
||||
"cleared_one": "Cleared {{count}} audit entry",
|
||||
"cleared_other": "Cleared {{count}} audit entries",
|
||||
"clearFailed": "Couldn't clear the audit log",
|
||||
"truncated": "Showing the {{returned}} most recent of {{total}} entries.",
|
||||
"on": "On",
|
||||
|
||||
@@ -94,7 +94,8 @@
|
||||
"fullHistory": "Full history",
|
||||
"fullHistoryHint": "Channels whose entire back-catalog is fetched, out of the ones you've requested full history for.",
|
||||
"left": "left",
|
||||
"leftHint": "Rough estimate to finish full-history backfill of {{count}} pending channel(s), based on the shared daily quota.",
|
||||
"leftHint_one": "Rough estimate to finish full-history backfill of {{count}} pending channel, based on the shared daily quota.",
|
||||
"leftHint_other": "Rough estimate to finish full-history backfill of {{count}} pending channels, based on the shared daily quota.",
|
||||
"myVideos": "My videos",
|
||||
"myVideosHint": "Total videos available across your channels.",
|
||||
"quotaLeft": "Quota left",
|
||||
@@ -125,11 +126,13 @@
|
||||
"noTagsYet": "No tags yet — make one with a row’s tag “+”"
|
||||
},
|
||||
"notify": {
|
||||
"synced": "Synced {{count}} subscriptions",
|
||||
"synced_one": "Synced {{count}} subscription",
|
||||
"synced_other": "Synced {{count}} subscriptions",
|
||||
"syncFailed": "Couldn't sync subscriptions",
|
||||
"unsubscribed": "Unsubscribed from {{name}} on YouTube",
|
||||
"unsubscribeFailed": "Couldn't unsubscribe",
|
||||
"fullHistoryRequested": "Full history requested for {{count}} channels",
|
||||
"fullHistoryRequested_one": "Full history requested for {{count}} channel",
|
||||
"fullHistoryRequested_other": "Full history requested for {{count}} channels",
|
||||
"fullHistoryFailed": "Couldn't request full history",
|
||||
"needYouTube": "Connect your YouTube account to do this",
|
||||
"connect": "Connect",
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
"itemCount_one": "{{formattedCount}} item",
|
||||
"itemCount_other": "{{formattedCount}} items",
|
||||
"accessRequestsTitle": "Access requests",
|
||||
"accessRequestsMessage": "{{count}} pending — review them on the Users page.",
|
||||
"accessRequestsMessage_one": "{{count}} pending — review it on the Users page.",
|
||||
"accessRequestsMessage_other": "{{count}} pending — review them on the Users page.",
|
||||
"accessRequestsReview": "Review",
|
||||
"demoTitle": "Demo account",
|
||||
"demoSharedNotice": "You're in the shared demo account. Everything you do here — playlists, hidden videos, settings — is communal and may be changed by other demo visitors at the same time.",
|
||||
@@ -33,7 +34,8 @@
|
||||
"lower": "Lower priority",
|
||||
"edit": "Click to type a priority (negatives allowed)"
|
||||
},
|
||||
"moreRefine": "{{count}} more — refine with search",
|
||||
"moreRefine_one": "{{count}} more — refine with search",
|
||||
"moreRefine_other": "{{count}} more — refine with search",
|
||||
"matchMode": "Match",
|
||||
"match": {
|
||||
"any": "Any",
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
"willReencode": "Will re-encode",
|
||||
"willCopy": "Instant (stream copy)",
|
||||
"create": "Create clip",
|
||||
"createN": "Create {{count}} clips",
|
||||
"createN_one": "Create {{count}} clip",
|
||||
"createN_other": "Create {{count}} clips",
|
||||
"created_one": "{{count}} clip added to your downloads",
|
||||
"created_other": "{{count}} clips added to your downloads",
|
||||
"failed": "Couldn’t create the clip",
|
||||
|
||||
@@ -40,12 +40,15 @@
|
||||
"total": "total",
|
||||
"countTooltip": "Your subscriptions vs. the whole shared catalog.",
|
||||
"paused": "paused",
|
||||
"syncing": "{{count}} syncing",
|
||||
"syncing_one": "{{count}} syncing",
|
||||
"syncing_other": "{{count}} syncing",
|
||||
"backfillingHistory": "fetching history",
|
||||
"working": "syncing…",
|
||||
"recentQueued": "{{count}} queued",
|
||||
"recentQueued_one": "{{count}} queued",
|
||||
"recentQueued_other": "{{count}} queued",
|
||||
"allSynced": "all synced",
|
||||
"withoutFullHistory": "{{count}} without full history",
|
||||
"withoutFullHistory_one": "{{count}} without full history",
|
||||
"withoutFullHistory_other": "{{count}} without full history",
|
||||
"fullHistoryTooltip": "Recent uploads only — click to fetch the rest.",
|
||||
"pause": "Pause sync",
|
||||
"resume": "Resume sync"
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
"menu": "Notifications actions",
|
||||
"sectionSystem": "System",
|
||||
"sectionActivity": "Activity",
|
||||
"andMore": "and {{count}} more",
|
||||
"andMore_one": "and {{count}} more",
|
||||
"andMore_other": "and {{count}} more",
|
||||
"openScheduler": "Open Scheduler",
|
||||
"openDownloads": "Open Downloads",
|
||||
"revertFailed": "Couldn't undo that — please try again",
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
"title": "You're connected",
|
||||
"importFailed": "Your YouTube account is connected, but we couldn't import your subscriptions — you can retry from Settings → Sync. ",
|
||||
"feedReady": "Your Feed is ready{{channels}}. Optionally, let Siftlode ",
|
||||
"feedReadyChannels": " ({{count}} channels)",
|
||||
"feedReadyChannels_one": " ({{count}} channel)",
|
||||
"feedReadyChannels_other": " ({{count}} channels)",
|
||||
"rationale": "<0>unsubscribe</0> from channels on YouTube for you — this needs an extra write permission. Skip it to stay read-only; you can always enable it later in Settings.",
|
||||
"retryImport": "Retry import",
|
||||
"enableUnsubscribe": "Enable unsubscribe",
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
"title": "Jump to…",
|
||||
"placeholder": "Search modules, channels, playlists…",
|
||||
"empty": "Nothing matches.",
|
||||
"results": "{{count}} result",
|
||||
"results_one": "{{count}} result",
|
||||
"results_other": "{{count}} results",
|
||||
"theme": "Theme: {{name}}",
|
||||
"videoCount": "{{count}} video",
|
||||
"videoCount_one": "{{count}} video",
|
||||
"videoCount_other": "{{count}} videos",
|
||||
"groups": {
|
||||
"modules": "Modules",
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
"listGroup": "Your playlists",
|
||||
"watchLater": "Watch later",
|
||||
"syncYoutube": "Sync from YouTube",
|
||||
"syncedToast": "Synced {{count}} playlists from YouTube",
|
||||
"syncedToast_one": "Synced {{count}} playlist from YouTube",
|
||||
"syncedToast_other": "Synced {{count}} playlists from YouTube",
|
||||
"syncFailed": "Couldn't sync from YouTube",
|
||||
"noneYet": "No playlists yet",
|
||||
"newPlaylist": "New playlist…",
|
||||
@@ -34,7 +35,8 @@
|
||||
"revertFailed": "Couldn't sync from YouTube",
|
||||
"pushTitle": "Sync to YouTube",
|
||||
"pushConfirm": "Sync",
|
||||
"pushPlanCreate": "Create a new YouTube playlist with {{count}} videos? (~{{units}} quota units; {{left}} left today.)",
|
||||
"pushPlanCreate_one": "Create a new YouTube playlist with {{count}} video? (~{{units}} quota units; {{left}} left today.)",
|
||||
"pushPlanCreate_other": "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.",
|
||||
@@ -53,7 +55,8 @@
|
||||
"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}} video(s) were skipped",
|
||||
"pushPartial_one": "Synced, but {{count}} video was skipped",
|
||||
"pushPartial_other": "Synced, but {{count}} videos were skipped",
|
||||
"pushFailed": "Couldn't sync to YouTube",
|
||||
"deleteHereOnly": "Delete here only",
|
||||
"deleteYtFailed": "Couldn't delete on YouTube; deleted here only",
|
||||
@@ -103,7 +106,8 @@
|
||||
"dragBlockedFilter": "Reordering by hand is off while a filter is applied.",
|
||||
"clearView": "Reset view",
|
||||
"saveOrder": "Save this order",
|
||||
"filteredCount": "{{count}} shown",
|
||||
"filteredCount_one": "{{count}} shown",
|
||||
"filteredCount_other": "{{count}} shown",
|
||||
"noneMatchFilter": "No videos match the filter.",
|
||||
"loadFailed": "Couldn't load this playlist",
|
||||
"reorderFailed": "Couldn't save the new order",
|
||||
|
||||
@@ -128,7 +128,8 @@
|
||||
"seasonTitle": "Season {{n}}",
|
||||
"specials": "Specials",
|
||||
"watchedFailed": "Couldn't update the watched state — please try again",
|
||||
"seasons": "{{count}} seasons",
|
||||
"seasons_one": "{{count}} season",
|
||||
"seasons_other": "{{count}} seasons",
|
||||
"unified": {
|
||||
"titles": "Titles",
|
||||
"episodes": "Episodes"
|
||||
@@ -136,7 +137,8 @@
|
||||
"series": {
|
||||
"seasons": "Seasons",
|
||||
"backToShow": "Back to show",
|
||||
"episodeCount": "{{count}} episodes",
|
||||
"episodeCount_one": "{{count}} episode",
|
||||
"episodeCount_other": "{{count}} episodes",
|
||||
"showFromStart": "Show from the start",
|
||||
"seasonFromStart": "Season from the start",
|
||||
"related": "Related shows",
|
||||
@@ -154,11 +156,13 @@
|
||||
"create": "Create",
|
||||
"search": "Filter collections…",
|
||||
"none": "No editable collections yet. Create one above.",
|
||||
"count": "{{count}} items",
|
||||
"count_one": "{{count}} item",
|
||||
"count_other": "{{count}} items",
|
||||
"delete": "Delete",
|
||||
"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_one": "Manage {{count}} existing collection",
|
||||
"others_other": "Manage {{count}} existing collections",
|
||||
"makeEditable": "Manage"
|
||||
},
|
||||
"player": {
|
||||
@@ -298,7 +302,8 @@
|
||||
"newPlaceholder": "New playlist name…",
|
||||
"create": "Create",
|
||||
"none": "No playlists yet. Create one above.",
|
||||
"count": "{{count}} items",
|
||||
"count_one": "{{count}} item",
|
||||
"count_other": "{{count}} items",
|
||||
"groupProgress": "{{in}} / {{size}}",
|
||||
"addFailed": "Couldn't add it to the playlist",
|
||||
"removeFailed": "Couldn't remove it from the playlist",
|
||||
@@ -319,7 +324,8 @@
|
||||
"layoutTree": "Tree view",
|
||||
"removeShow": "Remove whole show",
|
||||
"removeSeason": "Remove whole season",
|
||||
"episodes": "{{count}} episodes",
|
||||
"episodes_one": "{{count}} episode",
|
||||
"episodes_other": "{{count}} episodes",
|
||||
"seasonUnknown": "Episodes",
|
||||
"addShow": "Add whole show to a playlist",
|
||||
"addSeason": "Add season to a playlist",
|
||||
@@ -345,8 +351,10 @@
|
||||
"person": {
|
||||
"credits": "{{movies}} movies · {{shows}} shows",
|
||||
"filterBy": "Filter library by {{name}}",
|
||||
"movies": "Movies ({{count}})",
|
||||
"shows": "Shows ({{count}})",
|
||||
"movies_one": "Movies ({{count}})",
|
||||
"movies_other": "Movies ({{count}})",
|
||||
"shows_one": "Shows ({{count}})",
|
||||
"shows_other": "Shows ({{count}})",
|
||||
"empty": "No titles found for this person.",
|
||||
"born": "Born",
|
||||
"died": "Died",
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
"jobsTitle": "Jobs",
|
||||
"queueTitle": "Work queued",
|
||||
"quotaTitle": "Shared API quota",
|
||||
"everyMin": "every {{count}} min",
|
||||
"everyMin_one": "every {{count}} min",
|
||||
"everyMin_other": "every {{count}} min",
|
||||
"runningNow": "Running now…",
|
||||
"lastRun": "Last run {{time}}",
|
||||
"neverRun": "Hasn't run yet this session",
|
||||
@@ -115,7 +116,8 @@
|
||||
"purgeDiscovery": "Purge discovery",
|
||||
"purgeDiscoveryHint": "Delete all un-kept discovery content now (search results nobody watched/saved, and explored-but-unsubscribed channels) — ignoring the grace period.",
|
||||
"purgeConfirmTitle": "Purge discovery content?",
|
||||
"purgedDiscovery": "Deleted {{count}} discovery items",
|
||||
"purgedDiscovery_one": "Deleted {{count}} discovery item",
|
||||
"purgedDiscovery_other": "Deleted {{count}} discovery items",
|
||||
"result": {
|
||||
"new": "new videos",
|
||||
"failed": "failed",
|
||||
|
||||
@@ -147,7 +147,8 @@
|
||||
"resetHint": "Wipe the demo account's playlists, hidden/watched/saved videos and settings, then re-seed a few sample playlists.",
|
||||
"resetTitle": "Reset demo state?",
|
||||
"resetConfirm": "This clears everything the demo account has accumulated — playlists, hidden/watched/saved videos and settings — and re-seeds a few sample playlists. It can't be undone.",
|
||||
"resetDone": "Demo reset — {{count}} sample playlist(s) seeded",
|
||||
"resetDone_one": "Demo reset — {{count}} sample playlist seeded",
|
||||
"resetDone_other": "Demo reset — {{count}} sample playlists seeded",
|
||||
"resetFailed": "Couldn't reset the demo account",
|
||||
"removed": "Removed from the demo whitelist",
|
||||
"removeTitle": "Remove demo access?",
|
||||
@@ -158,7 +159,8 @@
|
||||
"noPending": "No pending requests.",
|
||||
"addPlaceholder": "Add an email directly…",
|
||||
"add": "Add",
|
||||
"decided": "{{count}} decided",
|
||||
"decided_one": "{{count}} decided",
|
||||
"decided_other": "{{count}} decided",
|
||||
"approved": "Approved {{email}} — they can sign in now",
|
||||
"approveFailed": "Couldn't approve the request",
|
||||
"denyFailed": "Couldn't deny the request",
|
||||
@@ -243,7 +245,8 @@
|
||||
},
|
||||
"count_one": "{{count}} event · newest first",
|
||||
"count_other": "{{count}} events · newest first",
|
||||
"capped": "showing the newest {{shown}} of {{count}}",
|
||||
"capped_one": "showing the newest {{shown}} of {{count}}",
|
||||
"capped_other": "showing the newest {{shown}} of {{count}}",
|
||||
"copy": "Copy",
|
||||
"copied_one": "Copied {{count}} event",
|
||||
"copied_other": "Copied {{count}} events",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"filters": "Filters",
|
||||
"activeCount": "{{count}} active",
|
||||
"activeCount_one": "{{count}} active",
|
||||
"activeCount_other": "{{count}} active",
|
||||
"clearAll": "Clear all",
|
||||
"resetDefaults": "Reset to defaults",
|
||||
"customize": "Customize sidebar",
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
"fullHistory": "Full history",
|
||||
"fullHistoryHint": "Channels whose entire back-catalog has been fetched, out of the ones you've requested full history for (opt in per channel on the Channels page).",
|
||||
"fullHistoryEta": "Full history ETA",
|
||||
"fullHistoryEtaHint": "Rough estimate to finish full-history backfill of {{count}} pending channel(s), based on the shared daily quota.",
|
||||
"fullHistoryEtaHint_one": "Rough estimate to finish full-history backfill of {{count}} pending channel, based on the shared daily quota.",
|
||||
"fullHistoryEtaHint_other": "Rough estimate to finish full-history backfill of {{count}} pending channels, based on the shared daily quota.",
|
||||
"myVideos": "My videos",
|
||||
"myVideosHint": "Total videos available to you across your subscribed channels.",
|
||||
"quotaLeft": "Quota left today",
|
||||
@@ -43,9 +44,11 @@
|
||||
"syncSubscriptionsHint": "Re-import your YouTube subscriptions and pull in any newly-followed channels.",
|
||||
"backfillEverything": "Backfill everything",
|
||||
"backfillEverythingHint": "Request full back-catalog backfill for every channel you're subscribed to. Older videos + complete search fill in as the shared daily quota allows.",
|
||||
"synced": "Synced {{count}} subscriptions",
|
||||
"synced_one": "Synced {{count}} subscription",
|
||||
"synced_other": "Synced {{count}} subscriptions",
|
||||
"syncFailed": "Couldn't sync subscriptions",
|
||||
"fullHistoryRequested": "Full history requested for {{count}} channels",
|
||||
"fullHistoryRequested_one": "Full history requested for {{count}} channel",
|
||||
"fullHistoryRequested_other": "Full history requested for {{count}} channels",
|
||||
"fullHistoryFailed": "Couldn't request full history",
|
||||
"admin": "Admin",
|
||||
"adminPauseHint": "Pause or resume the background sync for the whole app (all users).",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"title": "Manage tags",
|
||||
"channels": "{{count}} ch.",
|
||||
"channels_one": "{{count}} ch.",
|
||||
"channels_other": "{{count}} ch.",
|
||||
"onChannels": "Tagged channels",
|
||||
"delete": "Delete",
|
||||
"deleted": "Tag “{{name}}” deleted",
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
"clear": "Eseménynapló ürítése",
|
||||
"clearTitle": "Üríted az eseménynaplót?",
|
||||
"clearConfirm": "Véglegesen törlöd az összes naplóbejegyzést? Ez nem vonható vissza. (Egy bejegyzés arról, hogy te ürítetted, megmarad.)",
|
||||
"cleared": "{{count}} naplóbejegyzés törölve",
|
||||
"cleared_one": "{{count}} naplóbejegyzés törölve",
|
||||
"cleared_other": "{{count}} naplóbejegyzés törölve",
|
||||
"clearFailed": "Nem sikerült üríteni az eseménynaplót",
|
||||
"truncated": "A legutóbbi {{returned}} bejegyzés látszik a(z) {{total}}-ból.",
|
||||
"on": "Be",
|
||||
|
||||
@@ -94,7 +94,8 @@
|
||||
"fullHistory": "Teljes előzmény",
|
||||
"fullHistoryHint": "Csatornák, amelyek teljes archívuma le van töltve, azok közül, amelyekhez teljes előzményt kértél.",
|
||||
"left": "hátra",
|
||||
"leftHint": "Hozzávetőleges becslés {{count}} függőben lévő csatorna teljes előzményének behúzására, a megosztott napi kvóta alapján.",
|
||||
"leftHint_one": "Hozzávetőleges becslés {{count}} függőben lévő csatorna teljes előzményének behúzására, a megosztott napi kvóta alapján.",
|
||||
"leftHint_other": "Hozzávetőleges becslés {{count}} függőben lévő csatorna teljes előzményének behúzására, a megosztott napi kvóta alapján.",
|
||||
"myVideos": "Videóim",
|
||||
"myVideosHint": "A csatornáidon elérhető videók teljes száma.",
|
||||
"quotaLeft": "Maradék kvóta",
|
||||
@@ -125,11 +126,13 @@
|
||||
"noTagsYet": "Még nincs címkéd — egy sor címke-„+” gombjával hozhatsz létre"
|
||||
},
|
||||
"notify": {
|
||||
"synced": "{{count}} feliratkozás szinkronizálva",
|
||||
"synced_one": "{{count}} feliratkozás szinkronizálva",
|
||||
"synced_other": "{{count}} feliratkozás szinkronizálva",
|
||||
"syncFailed": "Nem sikerült szinkronizálni a feliratkozásokat",
|
||||
"unsubscribed": "Leiratkozva a(z) {{name}} csatornáról a YouTube-on",
|
||||
"unsubscribeFailed": "Nem sikerült leiratkozni",
|
||||
"fullHistoryRequested": "Teljes előzmény kérve {{count}} csatornához",
|
||||
"fullHistoryRequested_one": "Teljes előzmény kérve {{count}} csatornához",
|
||||
"fullHistoryRequested_other": "Teljes előzmény kérve {{count}} csatornához",
|
||||
"fullHistoryFailed": "Nem sikerült teljes előzményt kérni",
|
||||
"needYouTube": "Ehhez csatlakoztasd a YouTube-fiókod",
|
||||
"connect": "Csatlakoztatás",
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
"itemCount_one": "{{formattedCount}} elem",
|
||||
"itemCount_other": "{{formattedCount}} elem",
|
||||
"accessRequestsTitle": "Hozzáférési kérelmek",
|
||||
"accessRequestsMessage": "{{count}} függőben — nézd át a Felhasználók oldalon.",
|
||||
"accessRequestsMessage_one": "{{count}} függőben — nézd át a Felhasználók oldalon.",
|
||||
"accessRequestsMessage_other": "{{count}} függőben — nézd át a Felhasználók oldalon.",
|
||||
"accessRequestsReview": "Áttekintés",
|
||||
"demoTitle": "Demó fiók",
|
||||
"demoSharedNotice": "Egy közös demó fiókban vagy. Minden, amit itt csinálsz — lejátszási listák, elrejtett videók, beállítások — közös, és más demó látogatók egyszerre módosíthatják.",
|
||||
@@ -33,7 +34,8 @@
|
||||
"lower": "Prioritás csökkentése",
|
||||
"edit": "Kattints a prioritás beírásához (negatív is lehet)"
|
||||
},
|
||||
"moreRefine": "még {{count}} — finomíts kereséssel",
|
||||
"moreRefine_one": "még {{count}} — finomíts kereséssel",
|
||||
"moreRefine_other": "még {{count}} — finomíts kereséssel",
|
||||
"matchMode": "Egyezés",
|
||||
"match": {
|
||||
"any": "Bármelyik",
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
"willReencode": "Újrakódolás lesz",
|
||||
"willCopy": "Azonnali (másolás)",
|
||||
"create": "Klip létrehozása",
|
||||
"createN": "{{count}} klip létrehozása",
|
||||
"createN_one": "{{count}} klip létrehozása",
|
||||
"createN_other": "{{count}} klip létrehozása",
|
||||
"created_one": "{{count}} klip a letöltésekhez adva",
|
||||
"created_other": "{{count}} klip a letöltésekhez adva",
|
||||
"failed": "Nem sikerült létrehozni a klipet",
|
||||
|
||||
@@ -40,12 +40,15 @@
|
||||
"total": "összes",
|
||||
"countTooltip": "A feliratkozásaid a teljes megosztott katalógushoz képest.",
|
||||
"paused": "szüneteltetve",
|
||||
"syncing": "{{count}} szinkronizálás alatt",
|
||||
"syncing_one": "{{count}} szinkronizálás alatt",
|
||||
"syncing_other": "{{count}} szinkronizálás alatt",
|
||||
"backfillingHistory": "előzmény behúzása",
|
||||
"working": "szinkronizálás…",
|
||||
"recentQueued": "{{count}} sorban",
|
||||
"recentQueued_one": "{{count}} sorban",
|
||||
"recentQueued_other": "{{count}} sorban",
|
||||
"allSynced": "minden szinkronban",
|
||||
"withoutFullHistory": "{{count}} teljes előzmény nélkül",
|
||||
"withoutFullHistory_one": "{{count}} teljes előzmény nélkül",
|
||||
"withoutFullHistory_other": "{{count}} teljes előzmény nélkül",
|
||||
"fullHistoryTooltip": "Csak a legutóbbi feltöltések — kattints a többiért.",
|
||||
"pause": "Szinkron szüneteltetése",
|
||||
"resume": "Szinkron folytatása"
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
"menu": "Értesítések műveletei",
|
||||
"sectionSystem": "Rendszer",
|
||||
"sectionActivity": "Tevékenység",
|
||||
"andMore": "és még {{count}}",
|
||||
"andMore_one": "és még {{count}}",
|
||||
"andMore_other": "és még {{count}}",
|
||||
"openScheduler": "Ütemező megnyitása",
|
||||
"openDownloads": "Letöltések megnyitása",
|
||||
"revertFailed": "Nem sikerült visszavonni — próbáld újra",
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
"title": "Csatlakoztatva",
|
||||
"importFailed": "A YouTube-fiókod csatlakoztatva, de nem sikerült importálni a feliratkozásaidat — újrapróbálhatod a Beállítások → Szinkronizálás menüben. ",
|
||||
"feedReady": "A Feeded készen áll{{channels}}. Választhatóan engedélyezheted, hogy a Siftlode ",
|
||||
"feedReadyChannels": " ({{count}} csatorna)",
|
||||
"feedReadyChannels_one": " ({{count}} csatorna)",
|
||||
"feedReadyChannels_other": " ({{count}} csatorna)",
|
||||
"rationale": "<0>leiratkozzon</0> helyetted a YouTube-csatornákról — ehhez egy plusz írási engedély szükséges. Hagyd ki, ha csak olvasható módban szeretnél maradni; ezt később bármikor engedélyezheted a Beállításokban.",
|
||||
"retryImport": "Importálás újra",
|
||||
"enableUnsubscribe": "Leiratkozás engedélyezése",
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
"title": "Ugrás…",
|
||||
"placeholder": "Modul, csatorna, lista keresése…",
|
||||
"empty": "Nincs találat.",
|
||||
"results": "{{count}} találat",
|
||||
"results_one": "{{count}} találat",
|
||||
"results_other": "{{count}} találat",
|
||||
"theme": "Téma: {{name}}",
|
||||
"videoCount": "{{count}} videó",
|
||||
"videoCount_one": "{{count}} videó",
|
||||
"videoCount_other": "{{count}} videó",
|
||||
"groups": {
|
||||
"modules": "Modulok",
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
"listGroup": "Listáid",
|
||||
"watchLater": "Megnézem később",
|
||||
"syncYoutube": "Szinkronizálás a YouTube-ról",
|
||||
"syncedToast": "{{count}} lista szinkronizálva a YouTube-ról",
|
||||
"syncedToast_one": "{{count}} lista szinkronizálva a YouTube-ról",
|
||||
"syncedToast_other": "{{count}} lista szinkronizálva a YouTube-ról",
|
||||
"syncFailed": "Nem sikerült szinkronizálni a YouTube-ról",
|
||||
"noneYet": "Még nincs lejátszási lista",
|
||||
"newPlaylist": "Új lista…",
|
||||
@@ -34,7 +35,8 @@
|
||||
"revertFailed": "Nem sikerült szinkronizálni a YouTube-ról",
|
||||
"pushTitle": "Szinkronizálás a YouTube-ra",
|
||||
"pushConfirm": "Szinkronizálás",
|
||||
"pushPlanCreate": "Létrehozol egy új YouTube-listát {{count}} videóval? (~{{units}} kvótaegység; ma még {{left}} maradt.)",
|
||||
"pushPlanCreate_one": "Létrehozol egy új YouTube-listát {{count}} videóval? (~{{units}} kvótaegység; ma még {{left}} maradt.)",
|
||||
"pushPlanCreate_other": "Létrehozol egy új YouTube-listát {{count}} videóval? (~{{units}} kvótaegység; ma még {{left}} maradt.)",
|
||||
"mergeAddLocal_one": "{{count}} videó bekerül a Siftlode-listádba a YouTube-ról.",
|
||||
"mergeAddLocal_other": "{{count}} videó bekerül a Siftlode-listádba a YouTube-ról.",
|
||||
"mergeRemoveLocal_one": "{{count}} videó törlődik a Siftlode-listádból.",
|
||||
@@ -53,7 +55,8 @@
|
||||
"pushNoQuota": "Nincs elég YouTube-kvóta mára ({{left}}) ehhez a szinkronhoz (~{{units}} kell). Próbáld újra holnap.",
|
||||
"pushUpToDate": "A(z) „{{name}}” már szinkronban van a YouTube-bal",
|
||||
"pushDone": "„{{name}}” szinkronizálva a YouTube-ra",
|
||||
"pushPartial": "Szinkronizálva, de {{count}} videó kimaradt",
|
||||
"pushPartial_one": "Szinkronizálva, de {{count}} videó kimaradt",
|
||||
"pushPartial_other": "Szinkronizálva, de {{count}} videó kimaradt",
|
||||
"pushFailed": "Nem sikerült szinkronizálni a YouTube-ra",
|
||||
"deleteHereOnly": "Törlés csak itt",
|
||||
"deleteYtFailed": "Nem sikerült törölni a YouTube-on; csak itt törölve",
|
||||
@@ -103,7 +106,8 @@
|
||||
"dragBlockedFilter": "A kézi átrendezés ki van kapcsolva, amíg szűrő van érvényben.",
|
||||
"clearView": "Nézet visszaállítása",
|
||||
"saveOrder": "Sorrend mentése",
|
||||
"filteredCount": "{{count}} látszik",
|
||||
"filteredCount_one": "{{count}} látszik",
|
||||
"filteredCount_other": "{{count}} látszik",
|
||||
"noneMatchFilter": "Egy videó sem felel meg a szűrőnek.",
|
||||
"loadFailed": "Nem sikerült betölteni ezt a listát",
|
||||
"reorderFailed": "Nem sikerült elmenteni az új sorrendet",
|
||||
|
||||
@@ -128,7 +128,8 @@
|
||||
"seasonTitle": "{{n}}. évad",
|
||||
"specials": "Különkiadások",
|
||||
"watchedFailed": "Nem sikerült frissíteni a megnézett állapotot — próbáld újra",
|
||||
"seasons": "{{count}} évad",
|
||||
"seasons_one": "{{count}} évad",
|
||||
"seasons_other": "{{count}} évad",
|
||||
"unified": {
|
||||
"titles": "Címek",
|
||||
"episodes": "Epizódok"
|
||||
@@ -136,7 +137,8 @@
|
||||
"series": {
|
||||
"seasons": "Évadok",
|
||||
"backToShow": "Vissza a sorozathoz",
|
||||
"episodeCount": "{{count}} rész",
|
||||
"episodeCount_one": "{{count}} rész",
|
||||
"episodeCount_other": "{{count}} rész",
|
||||
"showFromStart": "Sorozat elejéről",
|
||||
"seasonFromStart": "Évad elejéről",
|
||||
"related": "Kapcsolódó sorozatok",
|
||||
@@ -154,11 +156,13 @@
|
||||
"create": "Létrehozás",
|
||||
"search": "Kollekciók szűrése…",
|
||||
"none": "Még nincs szerkeszthető kollekció. Hozz létre egyet fent.",
|
||||
"count": "{{count}} elem",
|
||||
"count_one": "{{count}} elem",
|
||||
"count_other": "{{count}} elem",
|
||||
"delete": "Törlés",
|
||||
"deleteConfirm": "Törlöd a(z) „{{title}}” kollekciót a Plexből? Ez minden felhasználót érint.",
|
||||
"note": "A változtatások a Plexbe íródnak, és minden kliensen/felhasználónál megjelennek.",
|
||||
"others": "{{count}} meglévő kollekció kezelése",
|
||||
"others_one": "{{count}} meglévő kollekció kezelése",
|
||||
"others_other": "{{count}} meglévő kollekció kezelése",
|
||||
"makeEditable": "Kezelem"
|
||||
},
|
||||
"player": {
|
||||
@@ -298,7 +302,8 @@
|
||||
"newPlaceholder": "Új lista neve…",
|
||||
"create": "Létrehozás",
|
||||
"none": "Még nincs lista. Hozz létre egyet fent.",
|
||||
"count": "{{count}} elem",
|
||||
"count_one": "{{count}} elem",
|
||||
"count_other": "{{count}} elem",
|
||||
"groupProgress": "{{in}} / {{size}}",
|
||||
"addFailed": "Nem sikerült hozzáadni a lejátszási listához",
|
||||
"removeFailed": "Nem sikerült eltávolítani a lejátszási listáról",
|
||||
@@ -319,7 +324,8 @@
|
||||
"layoutTree": "Fa nézet",
|
||||
"removeShow": "Egész sorozat eltávolítása",
|
||||
"removeSeason": "Egész évad eltávolítása",
|
||||
"episodes": "{{count}} epizód",
|
||||
"episodes_one": "{{count}} epizód",
|
||||
"episodes_other": "{{count}} epizód",
|
||||
"seasonUnknown": "Epizódok",
|
||||
"addShow": "Egész sorozat listához adása",
|
||||
"addSeason": "Évad listához adása",
|
||||
@@ -345,8 +351,10 @@
|
||||
"person": {
|
||||
"credits": "{{movies}} film · {{shows}} sorozat",
|
||||
"filterBy": "Szűrés erre: {{name}}",
|
||||
"movies": "Filmek ({{count}})",
|
||||
"shows": "Sorozatok ({{count}})",
|
||||
"movies_one": "Filmek ({{count}})",
|
||||
"movies_other": "Filmek ({{count}})",
|
||||
"shows_one": "Sorozatok ({{count}})",
|
||||
"shows_other": "Sorozatok ({{count}})",
|
||||
"empty": "Nincs találat ehhez a személyhez.",
|
||||
"born": "Született",
|
||||
"died": "Elhunyt",
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
"jobsTitle": "Feladatok",
|
||||
"queueTitle": "Sorban álló munka",
|
||||
"quotaTitle": "Közös API-kvóta",
|
||||
"everyMin": "{{count}} percenként",
|
||||
"everyMin_one": "{{count}} percenként",
|
||||
"everyMin_other": "{{count}} percenként",
|
||||
"runningNow": "Most fut…",
|
||||
"lastRun": "Utolsó futás {{time}}",
|
||||
"neverRun": "Ebben a munkamenetben még nem futott",
|
||||
@@ -115,7 +116,8 @@
|
||||
"purgeDiscovery": "Felfedezés ürítése",
|
||||
"purgeDiscoveryHint": "Most törli az összes meg nem tartott felfedezés-tartalmat (senki által meg nem nézett/mentett keresési találatok és felfedezett, de nem követett csatornák) — a türelmi időt figyelmen kívül hagyva.",
|
||||
"purgeConfirmTitle": "Felfedezés-tartalom törlése?",
|
||||
"purgedDiscovery": "{{count}} felfedezés-elem törölve",
|
||||
"purgedDiscovery_one": "{{count}} felfedezés-elem törölve",
|
||||
"purgedDiscovery_other": "{{count}} felfedezés-elem törölve",
|
||||
"result": {
|
||||
"new": "új videó",
|
||||
"failed": "sikertelen",
|
||||
|
||||
@@ -147,7 +147,8 @@
|
||||
"resetHint": "Törli a demó fiók lejátszási listáit, elrejtett/megnézett/mentett videóit és beállításait, majd újra létrehoz pár minta lejátszási listát.",
|
||||
"resetTitle": "Visszaállítod a demó állapotot?",
|
||||
"resetConfirm": "Ez törli mindazt, amit a demó fiók összegyűjtött — lejátszási listák, elrejtett/megnézett/mentett videók és beállítások —, és újra létrehoz pár minta lejátszási listát. Nem vonható vissza.",
|
||||
"resetDone": "Demó visszaállítva — {{count}} minta lejátszási lista létrehozva",
|
||||
"resetDone_one": "Demó visszaállítva — {{count}} minta lejátszási lista létrehozva",
|
||||
"resetDone_other": "Demó visszaállítva — {{count}} minta lejátszási lista létrehozva",
|
||||
"resetFailed": "Nem sikerült visszaállítani a demó fiókot",
|
||||
"removed": "Eltávolítva a demó fehérlistáról",
|
||||
"removeTitle": "Visszavonod a demó hozzáférést?",
|
||||
@@ -158,7 +159,8 @@
|
||||
"noPending": "Nincs függőben lévő kérelem.",
|
||||
"addPlaceholder": "E-mail közvetlen hozzáadása…",
|
||||
"add": "Hozzáadás",
|
||||
"decided": "{{count}} eldöntve",
|
||||
"decided_one": "{{count}} eldöntve",
|
||||
"decided_other": "{{count}} eldöntve",
|
||||
"approved": "Jóváhagyva: {{email}} — most már be tud jelentkezni",
|
||||
"approveFailed": "Nem sikerült jóváhagyni a kérelmet",
|
||||
"denyFailed": "Nem sikerült elutasítani a kérelmet",
|
||||
@@ -243,7 +245,8 @@
|
||||
},
|
||||
"count_one": "{{count}} esemény · a legújabb felül",
|
||||
"count_other": "{{count}} esemény · a legújabb felül",
|
||||
"capped": "a legújabb {{shown}} látszik a(z) {{count}} közül",
|
||||
"capped_one": "a legújabb {{shown}} látszik a(z) {{count}} közül",
|
||||
"capped_other": "a legújabb {{shown}} látszik a(z) {{count}} közül",
|
||||
"copy": "Másolás",
|
||||
"copied_one": "Kimásolva: {{count}} esemény",
|
||||
"copied_other": "Kimásolva: {{count}} esemény",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"filters": "Szűrők",
|
||||
"activeCount": "{{count}} aktív",
|
||||
"activeCount_one": "{{count}} aktív",
|
||||
"activeCount_other": "{{count}} aktív",
|
||||
"clearAll": "Összes törlése",
|
||||
"resetDefaults": "Visszaállítás alapértelmezettre",
|
||||
"customize": "Oldalsáv testreszabása",
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
"fullHistory": "Teljes előzmény",
|
||||
"fullHistoryHint": "Azok a csatornák, amelyek teljes archívuma be van húzva, azokból, amelyekhez teljes előzményt kértél (csatornánként választható a Csatornák oldalon).",
|
||||
"fullHistoryEta": "Teljes előzmény becsült ideje",
|
||||
"fullHistoryEtaHint": "Hozzávetőleges becslés {{count}} függőben lévő csatorna teljes előzményének behúzásához, a megosztott napi kvóta alapján.",
|
||||
"fullHistoryEtaHint_one": "Hozzávetőleges becslés {{count}} függőben lévő csatorna teljes előzményének behúzásához, a megosztott napi kvóta alapján.",
|
||||
"fullHistoryEtaHint_other": "Hozzávetőleges becslés {{count}} függőben lévő csatorna teljes előzményének behúzásához, a megosztott napi kvóta alapján.",
|
||||
"myVideos": "Saját videók",
|
||||
"myVideosHint": "A számodra elérhető videók összesen a feliratkozott csatornáidon.",
|
||||
"quotaLeft": "Ma maradt kvóta",
|
||||
@@ -43,9 +44,11 @@
|
||||
"syncSubscriptionsHint": "Újraimportálja a YouTube-feliratkozásaidat és behúzza az újonnan követett csatornákat.",
|
||||
"backfillEverything": "Minden videó behúzása",
|
||||
"backfillEverythingHint": "A teljes archívum behúzásának kérése minden csatornához, amelyre fel vagy iratkozva. A régebbi videók és a teljes keresés annyira töltődnek fel, amennyit a megosztott napi kvóta enged.",
|
||||
"synced": "{{count}} feliratkozás szinkronizálva",
|
||||
"synced_one": "{{count}} feliratkozás szinkronizálva",
|
||||
"synced_other": "{{count}} feliratkozás szinkronizálva",
|
||||
"syncFailed": "Nem sikerült szinkronizálni a feliratkozásokat",
|
||||
"fullHistoryRequested": "Teljes előzmény kérve {{count}} csatornához",
|
||||
"fullHistoryRequested_one": "Teljes előzmény kérve {{count}} csatornához",
|
||||
"fullHistoryRequested_other": "Teljes előzmény kérve {{count}} csatornához",
|
||||
"fullHistoryFailed": "Nem sikerült teljes előzményt kérni",
|
||||
"admin": "Adminisztrátor",
|
||||
"adminPauseHint": "A háttér-szinkronizálás szüneteltetése vagy folytatása az egész alkalmazásra (minden felhasználóra).",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"title": "Címkék kezelése",
|
||||
"channels": "{{count}} csat.",
|
||||
"channels_one": "{{count}} csat.",
|
||||
"channels_other": "{{count}} csat.",
|
||||
"onChannels": "Címkézett csatornák",
|
||||
"delete": "Törlés",
|
||||
"deleted": "„{{name}}” címke törölve",
|
||||
|
||||
@@ -6,6 +6,20 @@ import { describe, expect, it } from "vitest";
|
||||
|
||||
import i18n from "./index";
|
||||
|
||||
const mods = import.meta.glob("./locales/*/*.json", { eager: true }) as Record<
|
||||
string,
|
||||
{ default: Record<string, unknown> }
|
||||
>;
|
||||
|
||||
// Every leaf string as [dotted key, value].
|
||||
function leaves(obj: Record<string, unknown>, prefix = ""): [string, string][] {
|
||||
return Object.entries(obj).flatMap(([k, v]) => {
|
||||
const key = prefix ? `${prefix}.${k}` : k;
|
||||
if (v && typeof v === "object") return leaves(v as Record<string, unknown>, key);
|
||||
return typeof v === "string" ? [[key, v] as [string, string]] : [];
|
||||
});
|
||||
}
|
||||
|
||||
describe("counted copy", () => {
|
||||
it("the share link's expiry is singular for one day", async () => {
|
||||
await i18n.changeLanguage("en");
|
||||
@@ -22,3 +36,26 @@ describe("counted copy", () => {
|
||||
expect(i18n.t("downloads.share.views", { count: 0 })).toBe("0 views");
|
||||
});
|
||||
});
|
||||
|
||||
// E31: "1 seasons", "Synced 1 subscriptions" — a counted string written as one plain key reads plural at
|
||||
// one. So the rule is held for every string, not key by key: a value that carries {{count}} is a plural
|
||||
// pair (`_one` / `_other`), even where the two read the same today, so the next wording is a plural too.
|
||||
describe("every counted string is a plural pair", () => {
|
||||
it("no {{count}} in a key without a plural suffix, in any language", () => {
|
||||
const bare = Object.entries(mods).flatMap(([path, mod]) =>
|
||||
leaves(mod.default)
|
||||
.filter(([k, v]) => v.includes("{{count}}") && !/_(zero|one|two|few|many|other)$/.test(k))
|
||||
.map(([k]) => `${path.replace(/^.*locales\//, "")}: ${k}`),
|
||||
);
|
||||
expect(bare).toEqual([]);
|
||||
});
|
||||
|
||||
it("reads singular at one", async () => {
|
||||
await i18n.changeLanguage("en");
|
||||
expect(i18n.t("plex.seasons", { count: 1 })).toBe("1 season");
|
||||
expect(i18n.t("plex.seasons", { count: 3 })).toBe("3 seasons");
|
||||
expect(i18n.t("channels.notify.synced", { count: 1 })).toBe("Synced 1 subscription");
|
||||
expect(i18n.t("playlists.pushPartial", { count: 1 })).toBe("Synced, but 1 video was skipped");
|
||||
expect(i18n.t("playlists.pushPartial", { count: 2 })).toBe("Synced, but 2 videos were skipped");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user