-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Localization Support for Extension #5
base: main
Are you sure you want to change the base?
Conversation
WalkthroughThis pull request introduces localization support for a YouTube summarization extension by adding new JSON files for English and Turkish localization. It modifies several JavaScript files to utilize these localization strings, enhancing user interface elements and error handling. The manifest file is updated to reference localized messages for the extension's name and description. Additionally, HTML and JavaScript files are adjusted to support dynamic language selection and notifications, ensuring a more user-friendly experience for speakers of multiple languages. Changes
Possibly related PRs
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Outside diff range and nitpick comments (10)
src/content.js (4)
177-177
: Simplify conditional using optional chainingYou can simplify the condition by using optional chaining, which makes the code more concise and readable:
if (data?.summary) { // ... }Apply this diff:
-if (data && data.summary) { +if (data?.summary) {🧰 Tools
🪛 Biome (1.9.4)
[error] 177-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
224-224
: Consider removing console.log statements in productionThe
console.log
statements used for debugging may not be necessary in the production environment and could clutter the console.Consider removing or commenting out these statements:
// Line 224 -console.log(chrome.i18n.getMessage("summarizeButtonClicked")); // Line 260 -console.log(chrome.i18n.getMessage("summarizeButtonClicked"));Also applies to: 260-260
193-195
: Use more robust selectors for YouTube elementsThe DOM selector used to find the subscribe button is very specific and may break if YouTube updates their layout:
const subscribeBtnDiv = document.querySelector("#subscribe-button > ytd-button-renderer > yt-button-shape > a > yt-touch-feedback-shape > div");Consider using a more resilient selector. For example, selecting by ID or using a query that is less likely to change:
const subscribeBtnDiv = document.querySelector("#subscribe-button");Or use feature detection methods to ensure the button is accurately selected regardless of DOM changes.
3-3
: EnhancegetVideoIdFromUrl
to handle different URL formatsThe current implementation only extracts the video ID from URLs with a
v
parameter, but YouTube videos can have different URL formats, such ashttps://youtu.be/VIDEO_ID
.Consider enhancing the function to handle various YouTube URL formats:
function getVideoIdFromUrl(url) { const urlObj = new URL(url); let videoId = urlObj.searchParams.get('v'); if (!videoId && urlObj.hostname === 'youtu.be') { videoId = urlObj.pathname.slice(1); } return videoId; }src/popup.html (1)
3-3
: Update thelang
attribute to match the default localeThe
lang
attribute is set to'tr'
, but the default locale in your manifest is'en'
. This can affect accessibility tools and search engines.Consider setting the
lang
attribute to'en'
or dynamically updating it based on the user's selected language:-<html lang="tr"> +<html lang="en">Or use JavaScript to set it dynamically:
<html id="html-root">// In your popup.js document.getElementById('html-root').setAttribute('lang', chrome.i18n.getUILanguage());src/popup.js (3)
8-12
: Add error handling for storage operationsWhile the implementation is correct, it would be beneficial to handle potential storage errors.
chrome.storage.sync.get(['preferredLanguage'], (result) => { + if (chrome.runtime.lastError) { + console.error(chrome.i18n.getMessage("storageError"), chrome.runtime.lastError); + return; + } if (result.preferredLanguage) { languageSelect.value = result.preferredLanguage; } });
15-23
: Add error handling for storage operationsSimilar to the previous section, add error handling for the storage operation.
chrome.storage.sync.set({ preferredLanguage: selectedLanguage }, () => { + if (chrome.runtime.lastError) { + console.error(chrome.i18n.getMessage("storageError"), chrome.runtime.lastError); + return; + } console.log(chrome.i18n.getMessage("languageSavedConsoleLog"), selectedLanguage); showNotification(chrome.i18n.getMessage("languageSavedNotification")); });
57-67
: Use optional chaining for safer accessThe code can be improved using optional chaining as suggested by the static analysis.
-if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { +if (window.matchMedia?.('(prefers-color-scheme: dark)')?.matches) { document.body.classList.add('dark-mode'); }src/_locales/en/messages.json (1)
1-83
: Consider adding placeholders for dynamic contentSeveral error messages might need to include dynamic content (e.g., error details). Consider using Chrome i18n placeholders.
Example for
unexpectedError
:"unexpectedError": { - "message": "An unexpected error occurred:" + "message": "An unexpected error occurred: $ERROR$", + "placeholders": { + "error": { + "content": "$1" + } + } }src/_locales/tr/messages.json (1)
56-76
: Consider adding RTL support for error messagesTurkish text might need RTL (Right-to-Left) support in some contexts. Consider adding
dir="auto"
in the HTML elements where these error messages are displayed.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (6)
src/_locales/en/messages.json
(1 hunks)src/_locales/tr/messages.json
(1 hunks)src/content.js
(1 hunks)src/manifest.json
(1 hunks)src/popup.html
(1 hunks)src/popup.js
(1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/popup.js
[error] 56-57: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/content.js
[error] 177-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🔇 Additional comments (3)
src/popup.js (1)
26-40
: LGTM! Well-implemented notification system
The notification system is well-implemented with proper animation handling and cleanup.
src/manifest.json (1)
2-2
: LGTM! Verify i18n implementation completeness
The manifest changes correctly implement Chrome extension i18n support by:
- Adding the required
default_locale
field - Using proper message reference format for name and description
Let's verify the i18n implementation is complete:
Also applies to: 5-6
✅ Verification successful
i18n implementation is complete and correctly structured
The verification confirms that:
- Required locale structure exists with both English (en) and Turkish (tr) translations
- Both referenced message keys (
extensionName
andextensionDescription
) are properly defined in both language files
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify i18n implementation completeness
# Check if all required locale files exist
echo "Checking locale files structure..."
fd -t d . src/_locales
# Verify that messages referenced in manifest exist in locale files
echo "\nVerifying message keys exist in locale files..."
for key in "extensionName" "extensionDescription"; do
echo "\nChecking $key in locale files:"
rg "\"$key\"" src/_locales/*/messages.json
done
Length of output: 941
src/_locales/tr/messages.json (1)
1-83
: Verify translation completeness and consistency
The Turkish translations look good, but let's ensure completeness and consistency with the English locale.
✅ Verification successful
Let me try a different approach to verify the translations.
Turkish translations are complete and consistent with English locale
The verification shows that:
- All message keys from English locale are present in Turkish locale
- Both files have identical set of 27 keys
- No empty messages were found in Turkish translations
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify translation completeness and consistency
# Compare message keys between English and Turkish files
echo "Checking for missing translations..."
diff <(jq 'keys' src/_locales/en/messages.json | jq -r '.[]' | sort) \
<(jq 'keys' src/_locales/tr/messages.json | jq -r '.[]' | sort)
# Check for empty messages
echo "\nChecking for empty messages..."
jq -r 'to_entries[] | select(.value.message == "") | .key' src/_locales/tr/messages.json
Length of output: 493
Script:
#!/bin/bash
# Get all keys from English locale
echo "English keys:"
cat src/_locales/en/messages.json | jq 'keys[]' | sort
echo -e "\nTurkish keys:"
cat src/_locales/tr/messages.json | jq 'keys[]' | sort
echo -e "\nChecking for empty messages in Turkish locale:"
cat src/_locales/tr/messages.json | jq '.[] | select(.message == "")'
Length of output: 1376
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (4)
src/content.js (4)
8-10
: Add null check for msgKey parameterThe showMessage function should handle null/undefined message keys gracefully.
function showMessage(msgKey) { + if (!msgKey) { + console.warn('Message key is missing'); + return; + } const message = chrome.i18n.getMessage(msgKey) || msgKey; alert(message); }
44-68
: Extract button styling to a reusable functionBoth close and copy buttons share identical styling code. Consider extracting this to a helper function to improve maintainability and reduce duplication.
+function createStyledButton(textKey, isDarkMode) { + const button = document.createElement('button'); + button.textContent = chrome.i18n.getMessage(textKey); + button.style.marginTop = '10px'; + button.style.padding = '5px 10px'; + button.style.cursor = 'pointer'; + button.style.backgroundColor = isDarkMode ? '#555' : '#f0f0f0'; + button.style.color = isDarkMode ? 'white' : 'black'; + button.style.border = isDarkMode ? '1px solid #777' : '1px solid #ccc'; + button.style.borderRadius = '4px'; + return button; +} -const closeButton = document.createElement('button'); -closeButton.textContent = chrome.i18n.getMessage("closeButtonText"); -closeButton.style.marginTop = '10px'; // ... (remove all styling) +const closeButton = createStyledButton("closeButtonText", isDarkMode); +closeButton.style.marginRight = '10px'; -const copyButton = document.createElement('button'); -copyButton.textContent = chrome.i18n.getMessage("copyButtonText"); -copyButton.style.marginTop = '10px'; // ... (remove all styling) +const copyButton = createStyledButton("copyButtonText", isDarkMode);
176-181
: Use optional chaining for safer property accessThe data.summary check could be simplified using optional chaining.
-if (data && data.summary) { +if (data?.summary) {🧰 Tools
🪛 Biome (1.9.4)
[error] 177-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
278-281
: Extract i18n initialization to a separate functionConsider moving the data-i18n localization logic to a separate function for better code organization.
+function initializeI18n() { + document.querySelectorAll('[data-i18n]').forEach(element => { + const key = element.getAttribute('data-i18n'); + element.textContent = chrome.i18n.getMessage(key); + }); +} -document.querySelectorAll('[data-i18n]').forEach(element => { - const key = element.getAttribute('data-i18n'); - element.textContent = chrome.i18n.getMessage(key); -}); +initializeI18n();
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
src/content.js
(1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/content.js
[error] 177-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🔇 Additional comments (2)
src/content.js (2)
140-140
:
Use localization key for the error message
The error message is still hardcoded, breaking localization support.
-showMessage("No video ID found. Cannot get transcript.");
+showMessage("noVideoIdError");
155-163
:
Parameterize the server URL for different environments
The hardcoded localhost URL is not suitable for production use.
+const SERVER_URL = chrome.runtime.getURL('config.json');
+const config = await fetch(SERVER_URL).then(response => response.json());
-const response = await fetch(`http://localhost:8000/transcript?video_id=${videoId}&summary_language=${preferredLanguage}`, {
+const response = await fetch(`${config.apiUrl}/transcript?video_id=${videoId}&summary_language=${preferredLanguage}`, {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (2)
src/content.js (2)
14-106
: Extract common styles to reduce duplicationThe modal dialog implementation has duplicate styling code for buttons. Consider extracting common styles into a helper function.
function applyCommonButtonStyles(button, isDarkMode) { const styles = { marginTop: '10px', padding: '5px 10px', cursor: 'pointer', backgroundColor: isDarkMode ? '#555' : '#f0f0f0', color: isDarkMode ? 'white' : 'black', border: isDarkMode ? '1px solid #777' : '1px solid #ccc', borderRadius: '4px' }; Object.assign(button.style, styles); } // Usage: applyCommonButtonStyles(closeButton, isDarkMode); applyCommonButtonStyles(copyButton, isDarkMode);
278-281
: Add error handling for invalid i18n keysThe localization of elements with data-i18n attributes should handle cases where the key doesn't exist.
document.querySelectorAll('[data-i18n]').forEach(element => { const key = element.getAttribute('data-i18n'); - element.textContent = chrome.i18n.getMessage(key); + const message = chrome.i18n.getMessage(key); + if (message) { + element.textContent = message; + } else { + console.warn(`Missing translation for key: ${key}`); + } });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
src/content.js
(1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/content.js
[error] 177-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🔇 Additional comments (3)
src/content.js (3)
3-4
: LGTM! Robust URL parsing and proper localization implementation
The changes improve code reliability by:
- Using the URL API for parsing instead of manual string manipulation
- Properly implementing localization with a fallback mechanism
Also applies to: 8-10
155-163
:
Parameterize the server URL for different environments
The hardcoded localhost URL needs to be configurable for different environments.
191-263
: 🛠️ Refactor suggestion
Extract summarize button creation logic to reduce duplication
The button creation and styling code is duplicated between the primary and fallback paths.
Summary by CodeRabbit
Release Notes
New Features
Improvements
Documentation
Screenshots