Fall back to English instead of showing raw keys
Every namespace the fork added -- main_tabs, feed, cards, watch, browse, search, player, and now account -- exists only in en.json, because the thirteen translated language files predate them. get_text() consults the embedded fallback dict and then gives up and returns the key, so a non-English UI read "main_tabs.watch" on its own tabs. This round made that worse by adding more English-only keys. The fallback dict now carries those namespaces verbatim from en.json. It does not translate anything -- a German UI shows English for these strings -- but nothing shows a dotted key, and keys added later degrade the same way instead of breaking. Translations that do exist still win: buttons.download is still "Herunterladen" in German. Verified across all fourteen language files: no key in the fork's namespaces resolves to itself in any of them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -78,9 +78,139 @@ class LocalizationManager:
|
||||
"check_app_updates": "Check for SageTube updates on startup",
|
||||
"check_beta_updates": "Receive Beta Updates"
|
||||
},
|
||||
# Only the keys added by SageTube live here; the rest of update_dialog
|
||||
# is in every language file already. Without this a non-English UI
|
||||
# would show the raw key for the buttons below.
|
||||
# --- SageTube's own strings -------------------------------------
|
||||
# These namespaces exist only in en.json: the fork added them and the
|
||||
# thirteen translated files predate them. get_text() falls back to this
|
||||
# dict before giving up and returning the key itself, so without these
|
||||
# a non-English UI literally reads "main_tabs.watch" on its tabs.
|
||||
# Keep in step with en.json when adding keys; translating the language
|
||||
# files is the separate, larger job.
|
||||
"main_tabs": {
|
||||
"watch": "Watch",
|
||||
"search": "Search",
|
||||
"feed": "Feed",
|
||||
"browse": "Browse",
|
||||
"downloads": "Downloads"
|
||||
},
|
||||
"search": {
|
||||
"placeholder": "Search YouTube...",
|
||||
"button": "Search",
|
||||
"searching": "Searching...",
|
||||
"results_count": "{count} results",
|
||||
"failed": "Search failed: {error}",
|
||||
"button_tooltip": "Search YouTube"
|
||||
},
|
||||
"browse": {
|
||||
"placeholder": "Paste a channel or playlist URL...",
|
||||
"open": "Open",
|
||||
"subscribe": "Subscribe",
|
||||
"unsubscribe": "Unsubscribe",
|
||||
"play_all": "Play all",
|
||||
"download_playlist": "Download",
|
||||
"tab_videos": "Videos",
|
||||
"tab_shorts": "Shorts",
|
||||
"tab_live": "Live",
|
||||
"loading": "Loading...",
|
||||
"entry_count": "{count} videos",
|
||||
"failed": "Failed to load: {error}",
|
||||
"hint": "Open a channel (youtube.com/@name) or playlist URL, or navigate here from Search.",
|
||||
"open_tooltip": "Open this channel or playlist",
|
||||
"subscribe_tooltip": "Follow this channel so its uploads appear in your Feed",
|
||||
"unsubscribe_tooltip": "Stop following this channel",
|
||||
"play_all_tooltip": "Queue everything loaded here",
|
||||
"download_playlist_tooltip": "Open this playlist in Downloads",
|
||||
"queued_loaded": "Queued {count} loaded videos — press Load more first to queue the rest"
|
||||
},
|
||||
"feed": {
|
||||
"mode_local": "Local subscriptions",
|
||||
"mode_account": "YouTube account (cookies)",
|
||||
"refresh": "Refresh",
|
||||
"subscriptions": "Subscriptions",
|
||||
"no_subscriptions": "No subscriptions yet - subscribe from a channel page in Browse",
|
||||
"refreshing": "Refreshing... {done}/{total}",
|
||||
"refreshed": "{count} videos in feed",
|
||||
"channel_failed": "A channel failed to refresh: {error}",
|
||||
"fetching_account": "Fetching your subscription feed...",
|
||||
"account_failed": "Account feed failed (are cookies valid?): {error}",
|
||||
"subscribed": "Subscribed to {title}",
|
||||
"unsubscribed": "Unsubscribed from {title}",
|
||||
"open_channel": "Open channel",
|
||||
"refresh_tooltip": "Fetch the latest uploads from every subscribed channel",
|
||||
"mode_tooltip": "Where the feed comes from: your local subscriptions, or your signed-in YouTube account",
|
||||
"refreshed_with_failures": "{count} videos — {failed} channel(s) could not be reached",
|
||||
"account_needs_refresh": "Press Refresh to load your account feed",
|
||||
"empty_no_subscriptions": "No subscriptions yet.\n\nFind channels in Search or Browse, then use Subscribe to follow them — their new uploads will appear here.",
|
||||
"empty_not_refreshed": "Nothing here yet.\n\nPress Refresh to fetch the latest uploads from your subscriptions.",
|
||||
"sign_in": "Sign in with cookies…",
|
||||
"sign_in_tooltip": "Use your YouTube account via browser cookies, which enables the account feed",
|
||||
"account_requires_cookies": "Requires signing in with cookies"
|
||||
},
|
||||
"cards": {
|
||||
"play": "▶ Play",
|
||||
"queue": "+ Queue",
|
||||
"download": "⬇",
|
||||
"load_more": "Load more",
|
||||
"empty": "Nothing here yet",
|
||||
"play_tooltip": "Play this video now",
|
||||
"queue_tooltip": "Add to the play queue",
|
||||
"download_tooltip": "Open in Downloads with this video ready to analyse",
|
||||
"load_more_tooltip": "Load the next page of results"
|
||||
},
|
||||
"watch": {
|
||||
"clear_queue": "Clear queue"
|
||||
},
|
||||
"player": {
|
||||
"quality_auto": "Auto",
|
||||
"subtitles": "CC",
|
||||
"unavailable": "Video player unavailable",
|
||||
"now_playing": "Now Playing",
|
||||
"queue": "Queue",
|
||||
"play": "Play",
|
||||
"pause": "Pause",
|
||||
"stream_stalled": "Stream failed to start after several attempts - YouTube may be throttling. Try again or pick a lower quality.",
|
||||
"play_pause": "Play / pause (Space)",
|
||||
"fullscreen": "Fullscreen (F)",
|
||||
"seek_tooltip": "Seek through the video",
|
||||
"quality_tooltip": "Maximum playback resolution",
|
||||
"speed_tooltip": "Playback speed",
|
||||
"volume_tooltip": "Volume",
|
||||
"subtitles_tooltip": "Toggle subtitles (C)",
|
||||
"previous": "Previous in queue (P)",
|
||||
"next": "Next in queue (N)",
|
||||
"buffering": "Buffering…",
|
||||
"act_play_pause": "Play / pause",
|
||||
"act_seek_back_5": "Back 5 seconds",
|
||||
"act_seek_fwd_5": "Forward 5 seconds",
|
||||
"act_seek_back_10": "Back 10 seconds",
|
||||
"act_seek_fwd_10": "Forward 10 seconds",
|
||||
"act_seek_back_1": "Back 1 second",
|
||||
"act_seek_fwd_1": "Forward 1 second",
|
||||
"act_frame_back": "Previous frame",
|
||||
"act_frame_fwd": "Next frame",
|
||||
"act_vol_up": "Volume up",
|
||||
"act_vol_down": "Volume down",
|
||||
"act_mute": "Mute",
|
||||
"act_unmute": "Unmute",
|
||||
"act_speed_up": "Speed up",
|
||||
"act_speed_down": "Slow down",
|
||||
"act_speed_reset": "Normal speed",
|
||||
"act_subtitles": "Subtitles on / off",
|
||||
"act_fullscreen": "Fullscreen",
|
||||
"act_leave_fullscreen": "Leave fullscreen",
|
||||
"act_next": "Next in queue",
|
||||
"act_previous": "Previous",
|
||||
"act_start": "Back to start",
|
||||
"act_end": "Jump to end",
|
||||
"act_copy_url": "Copy video link",
|
||||
"act_open_browser": "Open in browser"
|
||||
},
|
||||
"account": {
|
||||
"signed_out": "Not signed in",
|
||||
"signed_out_tooltip": "SageTube is not using a YouTube account. Sign in with browser cookies to use your subscription feed and reach age-restricted or members-only videos.",
|
||||
"signed_in": "Account: {source}",
|
||||
"signed_in_tooltip": "Using cookies from {source}. Click to change or clear them.",
|
||||
"source_file": "cookie file"
|
||||
},
|
||||
"update_dialog": {
|
||||
"skip_version": "Skip This Version",
|
||||
"skip_version_tooltip": "Never offer {version} again. Later versions will still be shown.",
|
||||
|
||||
Reference in New Issue
Block a user