Owner answers to the E11 S5 raises (2026-09-13): 1 → A, 2 → "Feed" in every language, 3 → translate the
proxy label and fix every config key missing in BOTH languages ("maintenance", "tmdb" — old bugs).
Focus across a view change (1-A). Opening a Plex title from Home's rail, a channel from the Channels
table or a title from a Plex grid switches the page or the sub-view, which unmounts the list; Back used
to hand focus to <body>, so the next `j` started over at the top. The YouTube player (an overlay)
already restored onto the card.
- `lib/listNav`: `navPosition()` (list's place in reading order, the page's list count, item index)
and `restoreNavPosition()`: focuses the item once the page has as many lists on screen as when it was
left, polls on a timer (a hidden tab runs no animation frames), gives up after 2 s or at once when
something already holds focus, focuses without scrolling (the scroll restore owns the position).
- `lib/history`: `rememberNavPosition()` stamps `sfNav` onto the entry being left and returns the state
without it (a new entry must not inherit it); one popstate listener restores and spends the stamp,
so a later landing on the same entry (an overlay closing over it) cannot pull focus to an old item.
- Called before every view push: `setPage`, `openChannel`, `enterYtSearch`, `useHistorySubview.open`,
the Channels tab push. `navPosition.wiring.contract.test` fails on any `history.pushState(` without
it (the overlay stack's own push is the one exemption).
"Feed" (2). The module is "Feed" in both languages: every "hírfolyam" in the Hungarian UI (≈45 strings,
suffixed: Feedből, Feeded, Feedben…) and the prose "feed" in English that means the module ("your
Feed", "Hide from Feed"); "RSS feed" keeps its meaning. The welcome email says it too.
Backend ids without a name (3). The Configuration page showed `maintenance`, `tmdb`,
`maintenance_revalidate_batch`, `download_upload_max_bytes`, `audit_retention_days`, `plex_overlay_map`,
`tmdb_api_key` and `tmdb_language` as raw identifiers — the lookup falls back to the id, and the i18n
parity test stayed green because both languages missed the same keys. Added labels + hints (EN/HU),
the two groups (and their tab order), the missing `scheduler.jobDesc.demo_reset`, removed the stale
`plex_sync_interval_min` field, and "YouTube API kimenő proxy". `i18n/backendIds.contract.test` reads
`sysconfig.SPECS`, `scheduler.JOB_INTERVALS` and the audit/quota action enums from the backend sources
and fails on an id without its name in either language, or a name left for an id the backend dropped.
56 lines
2.8 KiB
JSON
56 lines
2.8 KiB
JSON
{
|
|
"tabs": {
|
|
"overview": "Overview",
|
|
"system": "System"
|
|
},
|
|
"title": "API quota usage",
|
|
"rangeDays": "{{count}}d",
|
|
"rangeLabel": "Time range",
|
|
"introBefore": "YouTube Data API units attributed by who triggered the spend. ",
|
|
"introSystem": "System",
|
|
"introAfter": " is shared background work (scheduled backfill, enrichment, resync) that isn't tied to one person.",
|
|
"loading": "Loading…",
|
|
"noData": "No data.",
|
|
"dailyTotal": "Daily total ({{count}}d · {{units}} units)",
|
|
"noUsageInRange": "No usage in this range.",
|
|
"dailyTooltip": "{{day}}: {{units}} units",
|
|
"system": "System (background)",
|
|
"sync": {
|
|
"myStatus": "My sync status",
|
|
"channels": "Channels",
|
|
"channelsHint": "How many channels you're subscribed to.",
|
|
"recentSynced": "Recent synced",
|
|
"recentSyncedHint": "Channels whose recent uploads (~last year) are already in the local database, so they show in your Feed.",
|
|
"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.",
|
|
"myVideos": "My videos",
|
|
"myVideosHint": "Total videos available to you across your subscribed channels.",
|
|
"quotaLeft": "Quota left today",
|
|
"quotaLeftHint": "Shared YouTube API budget remaining today (resets midnight US Pacific). Backfill yields to it.",
|
|
"loading": "Loading…",
|
|
"apiUsage": "Your API usage",
|
|
"today": "Today",
|
|
"todayHint": "YouTube API units your own actions used today (resets midnight US Pacific). Background sync isn't counted here.",
|
|
"last7d": "Last 7 days",
|
|
"last30d": "Last 30 days",
|
|
"allTime": "All time",
|
|
"byAction": "By action (30d)",
|
|
"noUsage": "No usage yet.",
|
|
"actions": "Actions",
|
|
"syncSubscriptions": "Sync subscriptions",
|
|
"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",
|
|
"syncFailed": "Sync failed",
|
|
"fullHistoryRequested": "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).",
|
|
"resumeBackgroundSync": "Resume background sync",
|
|
"pauseBackgroundSync": "Pause background sync"
|
|
}
|
|
}
|