feat: Add multi-language support with 4 new languages and validation#30
feat: Add multi-language support with 4 new languages and validation#30
Conversation
Add comprehensive multi-language translation system with Finnish, Swedish, German, and Spanish support, including centralized language registry, auto-detection, and CI validation. Features added: - Translation files for Finnish, Swedish, German, and Spanish (329 keys each) - Centralized language registry (src/renderer/src/lib/i18n/languages.ts) - Auto-detection utility using system locale (src/renderer/src/lib/i18n/detect.ts) - System locale IPC handler (src/main/ipc/system.ts) - UI language selection step in setup wizard (before CLI step) - Refactored SettingsPanel to use language registry - Translation validation script for CI (scripts/validate-translations.js) - CI workflow integration for translation validation Technical changes: - Updated Paraglide configuration to support 5 languages (en, fi, sv, de, es) - Added IPC channel system:get-locale for locale detection - Updated main.ts with auto-detection on first run - Added 3 new wizard message keys for UI language step - Updated CI workflow to validate translations on every PR/push Validation features: - Key count consistency checking - Placeholder consistency validation - Detection of untranslated content - Ignore list for technical terms and abbreviations - Exit codes for CI integration (0 = pass, 1 = fail) All translation files validated and build tested successfully.
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. WalkthroughAdds comprehensive internationalization support with translation files for German, Spanish, Finnish, and Swedish. Implements system locale detection via IPC, introduces translation validation infrastructure, and integrates UI language selection into the setup wizard with auto-detection capabilities. Changes
Sequence Diagram(s)sequenceDiagram
participant User as User (Renderer)
participant Wizard as SetupWizard Component
participant IPC as IPC Bridge
participant Main as Main Process
participant Store as Settings Storage
participant i18n as i18n System
User->>Wizard: Visit wizard (first run)
Wizard->>IPC: getSystemLocale()
IPC->>Main: invoke 'system:get-locale'
Main->>IPC: app.getLocale() result
IPC->>Wizard: system locale string
Wizard->>i18n: detectLanguage(systemLocale)
i18n-->>Wizard: detected language code
Wizard->>Wizard: display detected language<br/>populate LANGUAGES dropdown
User->>Wizard: select UI language
Wizard->>i18n: setLocale(selected)
i18n-->>Wizard: locale applied
Wizard->>Store: saveSettings({ui_language})
Wizard->>Wizard: proceed to next step
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
Summary of ChangesHello @tphakala, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the Birda GUI by introducing comprehensive multi-language support. It enables the application to be used in Finnish, Swedish, German, and Spanish, alongside English. The changes include a robust framework for managing language data, an intelligent system for automatically detecting and applying the user's preferred UI language, and a new validation process to maintain the quality and consistency of all translations. This initiative aims to provide a more localized and user-friendly experience for a wider international audience. Highlights
Changelog
Ignored Files
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/renderer/src/lib/components/SetupWizard.svelte`:
- Around line 163-172: The onMount block can assign null to selectedUiLanguage
if detectLanguage(systemLocale) returns null; change the assignment in the
onMount handler so selectedUiLanguage only gets detectLanguage(systemLocale)
when non-null, otherwise keep the default 'en' (e.g., use a null-coalescing
pattern or conditional) and ensure detectedLanguage is set accordingly; update
references to selectedUiLanguage/detectedLanguage used by handleUiLanguageNext
and isLocale so they never receive null from detectLanguage/getSystemLocale
calls.
🧹 Nitpick comments (6)
project.inlang/settings.json (1)
5-9: Consider pinning inlang module versions for reproducible builds.All four module URLs use
@latest, which means a breaking upstream release could silently affect your build. Pinning to specific versions (e.g.,@1.x.x) would improve reproducibility.src/renderer/src/lib/i18n/languages.ts (2)
6-23: Clean registry design.Well-structured single source of truth. One note: the
LANGUAGEScodes must stay in sync withproject.inlang/settings.jsonlanguageTags. Consider adding a comment pointing to this dependency so future contributors adding a language don't miss updating both.
38-39:getLanguageCodes()allocates a new array on every call.This is called from
detectLanguageon startup and potentially from hot paths. SinceLANGUAGESis a constant, consider caching the result.♻️ Optional: memoize the codes array
+const languageCodes = LANGUAGES.map((lang) => lang.code); + export function getLanguageCodes(): string[] { - return LANGUAGES.map((lang) => lang.code); + return languageCodes; }scripts/validate-translations.js (3)
139-160: False positives likely with common European cognates like "in", "on", "to".Words such as
in,on,to, andatexist as native words in German, Swedish, and other target languages. Even with threshold=3, a German sentence like "Klicken Sie in der Analyse auf den Model-Tab" could matchin,on,model,analysis(4 hits), triggering a false warning despite being properly translated.Consider either removing the shortest/most ambiguous words (
in,on,at,to) fromENGLISH_INDICATORS, or raising the threshold for these short words.
141-143: Skipping all texts with<or>is overly broad.Any translation containing a literal
<or>(e.g., comparison text like "values > 0") will bypass the English-word check entirely. If the intent is to skip HTML tags, a more targeted check like/<[a-zA-Z/]/.test(text)would be narrower.
279-287: Static analysis:forEachcallback should not return a value.Biome flags the implicit return from
console.loginside theforEacharrow. Use a block body or switch tofor...of.Proposed fix
if (result.errors.length > 0) { console.log(` Errors (${result.errors.length}):`); - result.errors.forEach((err) => console.log(` • ${err}`)); + for (const err of result.errors) { + console.log(` • ${err}`); + } } if (result.warnings.length > 0) { console.log(` Warnings (${result.warnings.length}):`); - result.warnings.forEach((warn) => console.log(` ⚠ ${warn}`)); + for (const warn of result.warnings) { + console.log(` ⚠ ${warn}`); + } }
| onMount(async () => { | ||
| // Auto-detect system language for UI language step | ||
| try { | ||
| const systemLocale = await getSystemLocale(); | ||
| detectedLanguage = detectLanguage(systemLocale); | ||
| selectedUiLanguage = detectedLanguage; | ||
| } catch { | ||
| // Detection failed, use English default | ||
| selectedUiLanguage = 'en'; | ||
| } |
There was a problem hiding this comment.
selectedUiLanguage can be set to null if detectLanguage returns no match.
If detectLanguage(systemLocale) returns null (OS locale doesn't map to a supported language), line 168 assigns null to selectedUiLanguage, overriding its 'en' default. This would leave the <select> with no valid selection and handleUiLanguageNext would skip saving entirely (since isLocale(null) is falsy).
Proposed fix
try {
const systemLocale = await getSystemLocale();
- detectedLanguage = detectLanguage(systemLocale);
- selectedUiLanguage = detectedLanguage;
+ const detected = detectLanguage(systemLocale);
+ detectedLanguage = detected;
+ if (detected) {
+ selectedUiLanguage = detected;
+ }
} catch {🧰 Tools
🪛 GitHub Actions: CI
[warning] Code style issues found. Run 'prettier --write' to fix.
🤖 Prompt for AI Agents
In `@src/renderer/src/lib/components/SetupWizard.svelte` around lines 163 - 172,
The onMount block can assign null to selectedUiLanguage if
detectLanguage(systemLocale) returns null; change the assignment in the onMount
handler so selectedUiLanguage only gets detectLanguage(systemLocale) when
non-null, otherwise keep the default 'en' (e.g., use a null-coalescing pattern
or conditional) and ensure detectedLanguage is set accordingly; update
references to selectedUiLanguage/detectedLanguage used by handleUiLanguageNext
and isLocale so they never receive null from detectLanguage/getSystemLocale
calls.
There was a problem hiding this comment.
This is a false positive. detectLanguage() return type is string, not string | null (detect.ts:10). It always returns either a matched language code or 'en' as fallback (line 22). The assignment at line 168 is safe.
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Read the detect.ts file to verify the return type and implementation
cat src/renderer/src/lib/i18n/detect.ts
Length of output: 764
@tphakala You're absolutely right, and I apologize for the confusion. I've confirmed that detectLanguage() has an explicit return type of string (line 10 in detect.ts) and always returns either a matched language code or falls back to 'en' (line 23). It never returns null.
The assignment selectedUiLanguage = detectedLanguage at line 168 is indeed safe. Thank you for catching this false positive and providing the reference! 🙏
🐰💭
(\/)
(••)
/>📚 learned something today!
| if (selectedUiLanguage && isLocale(selectedUiLanguage)) { | ||
| try { | ||
| await setSettings({ ui_language: selectedUiLanguage }); | ||
| void setLocale(selectedUiLanguage); |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Fixed in b01e17a. Added { reload: false } to match pattern in main.ts.
…lescing, disable Node.js rules in validation script
There was a problem hiding this comment.
Code Review
This pull request introduces comprehensive multi-language support, adding translations for Finnish, Swedish, German, and Spanish. The implementation is well-structured, featuring a centralized language registry, an auto-detection system for new users, and integration into both the setup wizard and settings panel. The inclusion of a CI validation script for translations is an excellent step towards ensuring long-term maintainability. The code is clean and follows good practices. I've found one issue in the setup wizard that could disrupt the user experience, which I've detailed in a specific comment. Overall, this is a great enhancement for the application.
| if (selectedUiLanguage && isLocale(selectedUiLanguage)) { | ||
| try { | ||
| await setSettings({ ui_language: selectedUiLanguage }); | ||
| void setLocale(selectedUiLanguage); |
There was a problem hiding this comment.
The setLocale function from Paraglide reloads the page by default. Calling it without { reload: false } will interrupt the setup wizard flow by causing a page refresh. This would prevent the user from proceeding to the next step.
To fix this, you should call setLocale with the reload: false option and await it within the try...catch block to ensure the language is applied without disrupting the wizard.
await setLocale(selectedUiLanguage, { reload: false });
…style
- Add { reload: false } to setLocale in handleUiLanguageNext to prevent page reload
- Add comment documenting sync requirement with project.inlang/settings.json
- Change forEach to for...of loops to avoid implicit return warnings
Previously, changing the UI language in settings required an app
restart. The setLocale call was missing the { reload: false } parameter
that was added to SetupWizard in PR #30.
Now the UI updates immediately when saving settings with a new language
selection, matching the behavior of the setup wizard.
Summary
This PR adds comprehensive multi-language support to Birda GUI with Finnish, Swedish, German, and Spanish translations, plus a centralized language registry, auto-detection system, and CI validation.
Changes
🌍 Translation Files
All translations:
{count},{path}, etc.)📦 Language Registry System
src/renderer/src/lib/i18n/languages.tsgetLanguage(),getLanguageCodes()🔍 Auto-Detection System
src/renderer/src/lib/i18n/detect.tssrc/main/ipc/system.tssystem:get-locale)src/renderer/src/main.ts🧙 Setup Wizard Integration
src/renderer/src/lib/components/SetupWizard.sveltewizard_uiLanguage_titlewizard_uiLanguage_subtitlewizard_uiLanguage_detected⚙️ Settings Panel Refactoring
src/renderer/src/lib/components/SettingsPanel.svelteUI_LANGUAGE_NAMESconstant$lib/i18n/languages🔌 IPC Infrastructure
src/main/ipc/handlers.ts- Register system handlerssrc/preload/index.ts- Addsystem:get-localeto allowlistsrc/renderer/src/lib/utils/ipc.ts- AddgetSystemLocale()wrapper✅ Translation Validation Script
scripts/validate-translations.js{placeholders}must match)package.jsonnpm run validate:translationsvalidatescript to include translation validation.github/workflows/ci.yml📝 Configuration Updates
project.inlang/settings.json["en", "fi", "sv", "de", "es"]messages/en.jsonVerification
Testing Checklist
Screenshots
(To be added by reviewer - test each language in the wizard and settings)
Notes
Migration Guide
For users:
For developers:
npm run validate:translationsto checkSummary by CodeRabbit
Release Notes
New Features
Chores