Translations update from Hosted Weblate - #178
Conversation
067baeb to
e7e17dc
Compare
Currently translated at 0.0% (0 of 130 strings) Translation: Cast Kodi/WebExtension Translate-URL: https://hosted.weblate.org/projects/castkodi/webextension/uk/
e7e17dc to
e694282
Compare
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughTamil and Ukrainian locale catalogs are added or updated with extension UI message keys and placeholder metadata. The Czech locale file is populated with messages for menus, popups, notifications, options, and YouTube labels. ChangesLocale message catalogs
Estimated code review effort: 1 (Trivial) | ~3 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/_locales/ta/messages.json (1)
1-2:⚠️ Potential issue | 🔴 CriticalCritical: Empty Tamil locale will break UI for ta-speaking users.
The Tamil locale file contains an empty JSON object with no message keys. The codebase uses
browser.i18n.getMessage()directly in bothl10n.js(line 83) andmenu.js(lines 41, 47, 58, 74) without fallback or validation logic. When a message key is not found,getMessage()returns an empty string, which is then assigned directly to UI elements (textContent, attributes, menu titles). This will render all labels, menu items, and text fields completely blank for Tamil speakers.This incomplete locale should not be merged unless:
- This PR is intended for review/staging only and will be populated by translators before release, OR
- A fallback mechanism is added to all
getMessage()calls before deployment.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/_locales/ta/messages.json` around lines 1 - 2, The Tamil locale file is completely empty and will cause all UI labels and menu items to render as blank strings for Tamil speakers since getMessage() returns empty strings for missing keys. Either populate the messages.json file with all required message keys and their Tamil translations to match the expected message structure used in l10n.js (line 83) and menu.js (lines 41, 47, 58, 74), OR add a fallback/validation wrapper around all getMessage() calls that returns a default language equivalent (such as English) when a translation key is not found. Choose one approach and ensure it is implemented consistently across all getMessage() usages to prevent UI breakage in production.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/_locales/uk/messages.json`:
- Around line 1-425: The Ukrainian locale file has all message keys defined with
empty string values, and since the browser's i18n fallback only triggers when
keys are missing entirely (not when empty), the UI renders blank for Ukrainian
users. To fix this, modify the code in l10n.js (in the area around lines 83-96
where messages are retrieved and assigned to DOM elements) and menu.js (in the
areas around lines 41, 47, 58, and 74-77 where menu titles are set) to add
explicit guards that check if the returned message from
browser.i18n.getMessage() is empty and, if so, fall back to retrieving the
English translation as a fallback value before assigning to DOM elements or menu
labels.
---
Outside diff comments:
In `@src/_locales/ta/messages.json`:
- Around line 1-2: The Tamil locale file is completely empty and will cause all
UI labels and menu items to render as blank strings for Tamil speakers since
getMessage() returns empty strings for missing keys. Either populate the
messages.json file with all required message keys and their Tamil translations
to match the expected message structure used in l10n.js (line 83) and menu.js
(lines 41, 47, 58, 74), OR add a fallback/validation wrapper around all
getMessage() calls that returns a default language equivalent (such as English)
when a translation key is not found. Choose one approach and ensure it is
implemented consistently across all getMessage() usages to prevent UI breakage
in production.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 32b4276e-6f00-4461-8b0f-3669e9fa5bc1
📒 Files selected for processing (2)
src/_locales/ta/messages.jsonsrc/_locales/uk/messages.json
| { | ||
| "popup_clear_title": { | ||
| "message": "" | ||
| }, | ||
| "notifications_notSupported_message": { | ||
| "message": "", | ||
| "placeholders": { | ||
| "number": { | ||
| "content": "$1" | ||
| }, | ||
| "name": { | ||
| "content": "$2" | ||
| } | ||
| } | ||
| }, | ||
| "popup_shutdown_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_hibernate_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_menuContextsBookmark_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "notifications_badAddress_message": { | ||
| "message": "", | ||
| "placeholders": { | ||
| "address": { | ||
| "content": "$1" | ||
| } | ||
| } | ||
| }, | ||
| "options_serverName_error": { | ||
| "message": "" | ||
| }, | ||
| "options_serverIntro_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_serverFix_title": { | ||
| "message": "" | ||
| }, | ||
| "options_permissionDescription_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_youtubeOrderReverse_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "labeler_youtube_unavailable": { | ||
| "message": "" | ||
| }, | ||
| "options_serverAddress_placeholder": { | ||
| "message": "" | ||
| }, | ||
| "menus_noName": { | ||
| "message": "", | ||
| "placeholders": { | ||
| "index": { | ||
| "content": "$1" | ||
| } | ||
| } | ||
| }, | ||
| "options_popupClipboardInput_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_forward_title": { | ||
| "message": "" | ||
| }, | ||
| "notifications_notGranted_message": { | ||
| "message": "" | ||
| }, | ||
| "options_menuActionsAdd_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_done_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "notifications_badAddress_title": { | ||
| "message": "" | ||
| }, | ||
| "options_youtubePlaylistPlaylist_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_menuContextsTab_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_contextmenu_title": { | ||
| "message": "" | ||
| }, | ||
| "options_menuActionsSend_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_previous_title": { | ||
| "message": "" | ||
| }, | ||
| "options_menuContextsLink_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_addsubtitle_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_serverRemove_alt": { | ||
| "message": "" | ||
| }, | ||
| "popup_down_title": { | ||
| "message": "" | ||
| }, | ||
| "notifications_unconfigured_message": { | ||
| "message": "" | ||
| }, | ||
| "options_menuContextsAudio_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_permissionButton_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_serverAddress_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_configure_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_opensubtitle_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_openquit_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_preferences_title": { | ||
| "message": "" | ||
| }, | ||
| "notifications_notFound_title": { | ||
| "message": "" | ||
| }, | ||
| "options_youtubePlaylistDescription_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_insert_title": { | ||
| "message": "" | ||
| }, | ||
| "options_serverAdd_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_suspend_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "menus_firstAdd": { | ||
| "message": "" | ||
| }, | ||
| "options_popupWheelNormal_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_youtubeOrderDescription_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_playItem_title": { | ||
| "message": "" | ||
| }, | ||
| "options_youtubePlaylistVideo_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_up_title": { | ||
| "message": "" | ||
| }, | ||
| "options_menuContextsFrame_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_right_title": { | ||
| "message": "" | ||
| }, | ||
| "options_serverResultLoading_title": { | ||
| "message": "" | ||
| }, | ||
| "menus_firstInsert": { | ||
| "message": "" | ||
| }, | ||
| "popup_sendtext_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "menus_secondAdd": { | ||
| "message": "" | ||
| }, | ||
| "options_youtubeOrderAsk_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_cancel_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "notifications_noLinks_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_openfeedback_title": { | ||
| "message": "" | ||
| }, | ||
| "options_popupWheelDisabled_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_opensendtext_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_select_title": { | ||
| "message": "" | ||
| }, | ||
| "menus_firstSend": { | ||
| "message": "" | ||
| }, | ||
| "options_popupWheelDescription_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_left_title": { | ||
| "message": "" | ||
| }, | ||
| "options_serverModeMulti_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "menus_secondInsert": { | ||
| "message": "" | ||
| }, | ||
| "popup_server_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_info_title": { | ||
| "message": "" | ||
| }, | ||
| "notifications_notSupported_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_mute_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_back_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_osd_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_fullscreen_title": { | ||
| "message": "" | ||
| }, | ||
| "menus_secondSend": { | ||
| "message": "" | ||
| }, | ||
| "options_serverName_placeholder": { | ||
| "message": "" | ||
| }, | ||
| "popup_add_title": { | ||
| "message": "" | ||
| }, | ||
| "options_serverNames_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_generalTitle_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "labeler_youtube_mix": { | ||
| "message": "" | ||
| }, | ||
| "popup_rewind_title": { | ||
| "message": "" | ||
| }, | ||
| "options_menuActionsInsert_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "notifications_notGranted_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_loading_title": { | ||
| "message": "" | ||
| }, | ||
| "options_youtubeOrderShuffle_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_popupWheelReverse_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_serverResultConnected_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_shuffle_title": { | ||
| "message": "" | ||
| }, | ||
| "options_popupTitle_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_menuTitle_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_serverAddress_title": { | ||
| "message": "" | ||
| }, | ||
| "notifications_noLink_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_home_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_repeat_title": { | ||
| "message": "" | ||
| }, | ||
| "options_youtubeOrderDefault_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_serverTitle_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "notifications_unknown_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_paste_title": { | ||
| "message": "" | ||
| }, | ||
| "notifications_notFound_message": { | ||
| "message": "", | ||
| "placeholders": { | ||
| "address": { | ||
| "content": "$1" | ||
| } | ||
| } | ||
| }, | ||
| "popup_web_title": { | ||
| "message": "" | ||
| }, | ||
| "manifest_description": { | ||
| "message": "" | ||
| }, | ||
| "popup_rate_title": { | ||
| "message": "" | ||
| }, | ||
| "options_menuActionsDescription_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_serverAddresses_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_serverModeSingle_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_volume_title": { | ||
| "message": "", | ||
| "placeholders": { | ||
| "value": { | ||
| "content": "$1" | ||
| } | ||
| } | ||
| }, | ||
| "notifications_noLinks_message": { | ||
| "message": "" | ||
| }, | ||
| "popup_pause_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_opendonate_title": { | ||
| "message": "" | ||
| }, | ||
| "options_menuContextsSelection_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_subtitle_placeholder": { | ||
| "message": "" | ||
| }, | ||
| "popup_removeItem_title": { | ||
| "message": "" | ||
| }, | ||
| "options_menuContextsPage_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_send_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_next_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_text_placeholder": { | ||
| "message": "" | ||
| }, | ||
| "options_youtubeTitle_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_reboot_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_serverRemove_title": { | ||
| "message": "" | ||
| }, | ||
| "options_menuContextsVideo_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_menuContextsDescription_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "notifications_noLink_message": { | ||
| "message": "", | ||
| "placeholders": { | ||
| "url": { | ||
| "content": "$1" | ||
| } | ||
| } | ||
| }, | ||
| "menus_firstParent": { | ||
| "message": "" | ||
| }, | ||
| "notifications_unconfigured_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_text_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_empty_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "options_serverFix_alt": { | ||
| "message": "" | ||
| }, | ||
| "popup_playerprocessinfo_title": { | ||
| "message": "" | ||
| }, | ||
| "options_generalHistoryInput_textcontent": { | ||
| "message": "" | ||
| }, | ||
| "popup_play_title": { | ||
| "message": "" | ||
| }, | ||
| "popup_stop_title": { | ||
| "message": "" | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify fallback logic for empty/missing messages.
# Test: Search for guards, fallback chains, or explicit English defaults around getMessage calls.
# Expected: Either fallback logic exists, or this PR is marked as work-in-progress.
rg -nB 2 -A 3 'getMessage' src/core/l10n.js src/core/menu.js | head -50Repository: regseb/castkodi
Length of output: 1747
🏁 Script executed:
cat -n src/core/l10n.jsRepository: regseb/castkodi
Length of output: 3999
🏁 Script executed:
cat -n src/core/menu.jsRepository: regseb/castkodi
Length of output: 6510
🏁 Script executed:
git log --oneline -n 5 src/_locales/uk/messages.json 2>/dev/null || echo "File is new in this PR"Repository: regseb/castkodi
Length of output: 107
🏁 Script executed:
# Check PR description, manifest, or any WIP indicators
head -100 README.md 2>/dev/null || echo "No README"Repository: regseb/castkodi
Length of output: 7086
🏁 Script executed:
# Verify English locale exists as a fallback option
ls -la src/_locales/*/messages.json | head -20Repository: regseb/castkodi
Length of output: 779
🏁 Script executed:
# Check if there's any i18n configuration or fallback mechanism in manifest
cat -n src/manifest.json 2>/dev/null | grep -A 10 -B 5 "default_locale\|i18n"Repository: regseb/castkodi
Length of output: 580
Critical: Empty Ukrainian translations will render the UI broken for uk-speaking users.
The Ukrainian locale file (src/_locales/uk/messages.json) defines all 424 message keys but with empty string values ("message": ""). Although the manifest specifies "default_locale": "en", the browser's i18n fallback only triggers when a key is missing entirely—not when the key exists with an empty value. Consequently, browser.i18n.getMessage() returns empty strings for all Ukrainian messages.
The code in l10n.js (lines 83–96) and menu.js (lines 41, 47, 58, 74–77) assigns these empty strings directly to DOM elements and menu titles without any guards, resulting in blank labels, invisible menu items, and broken form placeholders for Ukrainian users.
Before merging, either:
- Populate the Ukrainian translations to at least 80% completion, OR
- Add explicit fallback-to-English logic in
l10n.jsandmenu.jsto guard against empty messages fromgetMessage().
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/_locales/uk/messages.json` around lines 1 - 425, The Ukrainian locale
file has all message keys defined with empty string values, and since the
browser's i18n fallback only triggers when keys are missing entirely (not when
empty), the UI renders blank for Ukrainian users. To fix this, modify the code
in l10n.js (in the area around lines 83-96 where messages are retrieved and
assigned to DOM elements) and menu.js (in the areas around lines 41, 47, 58, and
74-77 where menu titles are set) to add explicit guards that check if the
returned message from browser.i18n.getMessage() is empty and, if so, fall back
to retrieving the English translation as a fallback value before assigning to
DOM elements or menu labels.
Currently translated at 100.0% (130 of 130 strings) Translation: Cast Kodi/WebExtension Translate-URL: https://hosted.weblate.org/projects/castkodi/webextension/ta/
Currently translated at 100.0% (130 of 130 strings) Translation: Cast Kodi/WebExtension Translate-URL: https://hosted.weblate.org/projects/castkodi/webextension/ta/
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/_locales/cs/messages.json`:
- Line 1: Populate the Czech catalog with every key from the English catalog,
ensuring each entry includes a message value and preserves the corresponding
placeholder metadata required by the locale tests. Keep English text or empty
translations where appropriate, but do not omit any English keys.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 54a8e200-a20f-44e3-9e32-151c64ccb028
📒 Files selected for processing (1)
src/_locales/cs/messages.json
Currently translated at 100.0% (130 of 130 strings) Translation: Cast Kodi/WebExtension Translate-URL: https://hosted.weblate.org/projects/castkodi/webextension/cs/
Translations update from Hosted Weblate for Cast Kodi/WebExtension.
Current translation status:
Summary by CodeRabbit