diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f1bb27b..141859e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,7 +12,7 @@ Please note that by participating in this project, you agree to abide by our [Co |------|-------------| | **Bug Reports** | Found a bug? Open an issue with repro steps (see template below). | | **Code** | Fix bugs, add features, or improve the extension / server / website. | -| **Translations** | Help localize the extension and website into more languages. See [TRANSLATION.md](website/TRANSLATION.md). | +| **Translations** | Help localize the extension and website into more languages. See [TRANSLATION.md](docs/TRANSLATION.md). | | **Documentation** | Improve docs, fix typos, or add missing examples. | | **Security** | Found a vulnerability? See [SECURITY.md](SECURITY.md) β€” do NOT open a public issue. | @@ -100,15 +100,23 @@ KoalaSync uses a **single source of truth** for all protocol constants in `share --- -## Pull Request Process +## Open Source Workflow & Pull Requests -1. **Branch** from `main` for your feature or fix. -2. **Test locally** on both Chrome and Firefox. -3. **Website changes**: Run `node website/build.js` and verify the compiled output in `www/`. -4. **Lint**: Ensure `npm run lint` passes with zero errors and zero warnings. -5. **Syntax**: Run `node -c` on every modified `.js` file. -6. **Protocol changes**: Update relevant documentation in `docs/`. -7. **Submit your PR** with a clear description and linked issue (if applicable). +If you are new to open-source contributions, follow these steps to propose your changes: + +1. **Fork the Repository**: Click the "Fork" button at the top right of this repository to create your own copy of KoalaSync. +2. **Clone your Fork**: `git clone https://github.com/YOUR-USERNAME/KoalaSync.git` +3. **Create a Branch**: `git checkout -b my-new-feature` (e.g. `feature/dark-mode` or `fix/translation-de`) +4. **Make your Changes**: Edit the files, then verify them locally. + - *Extension/Server changes*: Test on Chrome/Firefox and check `npm run lint`. + - *Website/Translation changes*: Run `node website/build.js` and check the output in `www/`. +5. **Commit and Push**: `git commit -m "Add my feature"` and `git push origin my-new-feature` +6. **Open a Pull Request (PR)**: Go to the original KoalaSync repository on GitHub and click "New Pull Request". + +### PR Code Requirements +- **Lint**: Ensure `npm run lint` passes with zero errors and warnings. +- **Syntax**: Run `node -c` on every modified `.js` file. +- **Protocol changes**: Update relevant documentation in `docs/`. --- @@ -140,14 +148,18 @@ If you cannot access the Status tab, include as much of the following manually: --- -## Translation Contributions +## Translation Contributions (Translators Welcome!) -KoalaSync supports 6 languages: English, German, French, Spanish, Portuguese (Brazilian), and Russian. +We welcome native speakers to help translate KoalaSync! You **do not** need deep programming knowledge to contribute translations. -To add or improve translations: -1. Edit the locale files in `website/locales/` (for the website). -2. For extension translations, see [TRANSLATION.md](website/TRANSLATION.md). -3. Run `node website/build.js` to regenerate the static site. +KoalaSync supports multiple languages. To add or improve translations: +1. Read the **[Translation Guide](docs/TRANSLATION.md)** first. It explains how our localization system works. +2. Edit the `.json` files in `website/locales/` (for the website) and `extension/locales/` (for the extension). +3. Test your translations locally by running: + - `node scripts/test-locales.js` (for extension) + - `node scripts/test-website-locales.mjs` (for website) + - `node website/build.js` (to build the site) +4. Follow the **Open Source Workflow** above (Fork -> Branch -> Edit -> PR) to submit your translations. --- diff --git a/README.md b/README.md index c192238..9865c47 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ The easiest and safest way to install KoalaSync is directly through the official Both the official KoalaSync website and the **v2.0 Browser Extension** feature full dynamic localization: - **Available Languages**: Support is included for 13 languages: English (`en`), German (`de`), French (`fr`), Spanish (`es`), Portuguese (Brazil) (`pt-BR`), Russian (`ru`), Italian (`it`), Polish (`pl`), Turkish (`tr`), Dutch (`nl`), Japanese (`ja`), Korean (`ko`), and European Portuguese (`pt`). - **Real-Time Extension Localization**: Inside the extension Settings panel, users can swap languages instantly. The entire interface, notifications, Empty States, and onboarding guides re-translate dynamically in real-time. -- **Contributing**: We welcome community translations for both the website and the extension! Please refer directly to the [TRANSLATION.md](website/TRANSLATION.md) guide for step-by-step instructions on how to audit, refine, or add new languages. +- **Contributing**: We welcome community translations for both the website and the extension! Please refer directly to the [TRANSLATION.md](docs/TRANSLATION.md) guide for step-by-step instructions on how to audit, refine, or add new languages. --- @@ -125,7 +125,7 @@ gh attestation verify dist/koalasync-chrome.zip \ - **[CHANGELOG.md](docs/CHANGELOG.md)**: Full version history for the extension and relay server. - **[TESTED_SERVICES.md](docs/TESTED_SERVICES.md)**: Detailed compatibility matrix of tested streaming platforms and known limitations. -- **[TRANSLATION.md](website/TRANSLATION.md)**: Translation and localization guide for contributors. +- **[TRANSLATION.md](docs/TRANSLATION.md)**: Translation and localization guide for contributors. - **[PRIVACY.md](docs/PRIVACY.md)**: Data Handling and Privacy Policy. - **[CONTRIBUTING.md](CONTRIBUTING.md)**: How to help make KoalaSync better. - **[CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)**: Our community standards and expectations. diff --git a/docs/README.md b/docs/README.md index e697788..edd0e49 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,3 +5,4 @@ This directory contains deep-dives into the KoalaSync protocol and architecture. - [HOW_IT_WORKS.md](HOW_IT_WORKS.md): Step-by-step walkthrough of every user flow, from room creation to synchronized playback. Ideal for store reviewers and manual testers. - [ARCHITECTURE.md](ARCHITECTURE.md): Communication flows, Dual Heartbeat, and Sync logic. - [SYNC_GUIDE.md](SYNC_GUIDE.md): Protocol constants and sync requirements. +- [TRANSLATION.md](TRANSLATION.md): Translation and localization guide for the extension and website. diff --git a/website/TRANSLATION.md b/docs/TRANSLATION.md similarity index 84% rename from website/TRANSLATION.md rename to docs/TRANSLATION.md index 98a23bc..39a9532 100644 --- a/website/TRANSLATION.md +++ b/docs/TRANSLATION.md @@ -57,15 +57,23 @@ Our legal pages have strict constraints to protect user privacy and avoid regula --- -## πŸ› οΈ Step-by-Step: Adding a New Language +## πŸ› οΈ Step-by-Step: Translating or Adding a Language -Adding a new language (e.g., Italian - `it`) is straightforward. Follow these four structured steps: +If you want to correct an existing language or add a new one, here is how you do it. -### Step 1: Create the Translation Dictionary -Create a new JSON file inside the locales directory named `[lang].json` (e.g., `website/locales/it.json`). -1. Copy the structure of [`website/locales/en.json`](file:///Users/koala/Documents/KoalaPlay/website/locales/en.json) to use as your baseline. -2. Translate all string values while keeping the JSON keys identical. -3. Configure the language metadata keys at the top of the file: +### Step 1: Fork and Clone the Repository +If you are an external contributor, you need to use the standard Open Source workflow: +1. Click the "Fork" button on GitHub to create your own copy of the repository. +2. Clone your fork locally: `git clone https://github.com/YOUR-USERNAME/KoalaSync.git` +3. Create a branch: `git checkout -b translation/my-language` + +### Step 2: Edit or Create the Dictionaries +KoalaSync requires two sets of translations: one for the **website** and one for the **browser extension**. + +**For the Website:** +1. Navigate to `website/locales/`. Edit an existing `[lang].json` or copy `en.json` to create a new one (e.g., `it.json`). +2. Translate all string values. Do not change the JSON keys. +3. If creating a new language, configure the metadata at the top: ```json { "LANG_CODE": "it", @@ -75,26 +83,30 @@ Create a new JSON file inside the locales directory named `[lang].json` (e.g., ` "LANG_TOGGLE_TEXT": "EN" } ``` +4. If creating a new language, register it in `website/build.js` by adding it to the `languages` array. -### Step 2: Register in the Compiler -Open the static site generator script [`website/build.js`](file:///Users/koala/Documents/KoalaPlay/website/build.js) and append your new language code to the active `languages` array: -```javascript -// Add 'it' to the array -const languages = ['en', 'de', 'fr', 'es', 'pt-BR', 'ru', 'it']; -``` +**For the Extension:** +1. Navigate to `extension/locales/`. Edit an existing `[lang].json` or copy `en.json` to create a new one. +2. Translate the values. -### Step 3: Run the Build Script -Execute the compiler from the root of the repository: +### Step 3: Verify Locally +Ensure your JSON files are valid and all keys match the English baseline: ```bash +# Tests the extension locales for missing keys or syntax errors +node scripts/test-locales.js + +# Tests the website locales for missing keys or syntax errors +node scripts/test-website-locales.mjs + +# Builds the website with your new translations node website/build.js ``` -The compiler will automatically: -1. Load the new JSON translation file. -2. Create the target subdirectory `/website/www/it/`. -3. Generate the compiled `/website/www/it/index.html` landing page, injecting correct relative assets and canonical metadata. -### Step 4: Update the Dashboard -Open this `TRANSLATION.md` file and add your language to the **Supported Languages Dashboard** table, marking it as `Auto-Generated` (unless manually verified). +### Step 4: Commit and Pull Request +1. Open this `TRANSLATION.md` file and add/update your language in the **Supported Languages Dashboard**. Mark it as `100% Manually Verified` if you are a native speaker checking an auto-generated file. +2. Commit your changes: `git commit -m "Update Italian translations"` +3. Push to your fork: `git push origin translation/my-language` +4. Open a **Pull Request** on the main KoalaSync repository on GitHub. --- diff --git a/extension/locales/i18n_plan.md b/extension/locales/i18n_plan.md deleted file mode 100644 index a27ed52..0000000 --- a/extension/locales/i18n_plan.md +++ /dev/null @@ -1,204 +0,0 @@ -# KoalaSync Browser Extension v2.0 - i18n Technical Implementation Plan - -Welcome, future Antigravity AI agent! This document is placed directly in the codebase at `/extension/locales/i18n_plan.md` to serve as a comprehensive architectural handbook for the next steps in adding **full internationalization (i18n) support to the browser extension itself** while maintaining 100% video-sync and background communication safety. - ---- - -## πŸ” Context & Audited Scope - -KoalaSync is a lightweight, premium browser extension (Chrome & Firefox Manifest V3) for synchronized video playback. The landing pages are already compiled dynamically in 6 languages: -* English (`en`) -* German (`de`) -* French (`fr`) -* Spanish (`es`) -* Portuguese (Brazil) (`pt-BR`) -* Russian (`ru`) - -Our goal is to build an identical, premium translation engine for the extension itself. - ---- - -## πŸ›οΈ Architectural Choice: Custom JSON Dictionary Engine (Approach B) - -We evaluated two paths: -1. **Approach A (Native `chrome.i18n` API):** Uses `_locales/` directory. Too rigidβ€”cannot support real-time dynamic switching inside the extension Settings dropdown without closing/re-opening the popup. -2. **Approach B (Custom Unified JSON Engine):** Uses flat JSON files matching our website files (`"KEY": "Value"`). Dynamically merges the target dictionary with baseline English `en.json` at runtime, programmatically providing an **airtight English fallback** and **real-time DOM translations** without popup reload. - -We chose **Approach B** for maximum compatibility, premium real-time toggling, and clean fallback safety. - ---- - -## πŸ”„ Resolve, Load, & State Flow - -1. **On launch:** Look for saved language in `chrome.storage.sync.get('locale')`. -2. **Fallback Autodetect:** If no saved language, read `navigator.language` or `chrome.i18n.getUILanguage()`. - * If the detected locale is supported, set as active. - * If not supported, default to English (`en`). -3. **Dictionary Resolution:** - * Asynchronously load the English baseline dictionary (`/extension/locales/en.json`). - * If the target language is different, load target JSON (e.g. `/extension/locales/de.json`) and execute `Object.assign({}, enDict, targetDict)`. This guarantees dynamic translation while cleanly falling back to English for any missing keys. -4. **DOM Replacements:** Scan for `data-i18n`, `data-i18n-title`, and `data-i18n-placeholder` attributes, and translate them on the fly. -5. **Persistence:** Save dynamic selection modifications from the dropdown into `chrome.storage.sync`. Trigger instant DOM re-translation on change. - ---- - -## πŸ“‚ Proposed File Structure - -``` -KoalaPlay/ -└── extension/ - β”œβ”€β”€ locales/ # [NEW] Contains flat translation maps - β”‚ β”œβ”€β”€ i18n_plan.md # This roadmap file - β”‚ β”œβ”€β”€ en.json # Flat English baseline keys - β”‚ β”œβ”€β”€ de.json # German keys - β”‚ β”œβ”€β”€ fr.json # French keys - β”‚ β”œβ”€β”€ es.json # Spanish keys - β”‚ β”œβ”€β”€ pt-BR.json # Portuguese (Brasil) keys - β”‚ └── ru.json # Russian keys - β”œβ”€β”€ i18n.js # [NEW] ESM translation engine module - β”œβ”€β”€ popup.html # Modified with data-i18n attributes - β”œβ”€β”€ popup.js # Modified to initialize locales and update variables - └── background.js # Modified to push localized notification alerts -``` - ---- - -## πŸ› οΈ Draft Code Snippets - -### 1. `i18n.js` (Zero-Dependency Engine Module) -```javascript -// extension/i18n.js -export const SUPPORTED_LANGUAGES = ['en', 'de', 'fr', 'es', 'pt-BR', 'ru']; -export const DEFAULT_LANGUAGE = 'en'; - -let activeDictionary = {}; - -export async function loadLocale(langCode) { - const resolvedLang = SUPPORTED_LANGUAGES.includes(langCode) ? langCode : DEFAULT_LANGUAGE; - try { - const enResponse = await fetch(chrome.runtime.getURL(`locales/${DEFAULT_LANGUAGE}.json`)); - const enDict = await enResponse.json(); - - if (resolvedLang === DEFAULT_LANGUAGE) { - activeDictionary = enDict; - return; - } - - const targetResponse = await fetch(chrome.runtime.getURL(`locales/${resolvedLang}.json`)); - const targetDict = await targetResponse.json(); - - activeDictionary = Object.assign({}, enDict, targetDict); - } catch (err) { - console.error('[i18n] Failed to load dictionary. Falling back to English:', err); - const rescue = await fetch(chrome.runtime.getURL(`locales/${DEFAULT_LANGUAGE}.json`)); - activeDictionary = await rescue.json(); - } -} - -export function getMessage(key) { - return activeDictionary[key] || key; -} - -export function translateDOM() { - // Translate text nodes - document.querySelectorAll('[data-i18n]').forEach(el => { - const key = el.getAttribute('data-i18n'); - const translated = getMessage(key); - const img = el.querySelector('img'); - if (img) { - el.innerHTML = ''; - el.appendChild(img); - el.appendChild(document.createTextNode(' ' + translated)); - } else { - el.textContent = translated; - } - }); - - // Translate tooltips - document.querySelectorAll('[data-i18n-title]').forEach(el => { - const key = el.getAttribute('data-i18n-title'); - el.setAttribute('title', getMessage(key)); - }); - - // Translate placeholders - document.querySelectorAll('[data-i18n-placeholder]').forEach(el => { - const key = el.getAttribute('data-i18n-placeholder'); - el.setAttribute('placeholder', getMessage(key)); - }); -} -``` - -### 2. Markup Changes (`popup.html`) -* Annotate text elements: `` -* Add Language Dropdown in the Settings Panel: - ```html -
- - -
- ``` - -### 3. Dynamic Script Wiring (`popup.js`) -* Import our engine: `import { loadLocale, translateDOM, getMessage } from './i18n.js';` -* Initialize during startup: - ```javascript - async function init() { - const data = await chrome.storage.sync.get(['locale', ...]); - let activeLang = data.locale; - if (!activeLang) { - const systemLang = (navigator.language || chrome.i18n.getUILanguage()).split('-')[0]; - activeLang = ['en', 'de', 'fr', 'es', 'pt', 'ru'].includes(systemLang) ? (systemLang === 'pt' ? 'pt-BR' : systemLang) : 'en'; - chrome.storage.sync.set({ locale: activeLang }); - } - await loadLocale(activeLang); - translateDOM(); - - // Select matching option in selector - const langSelector = document.getElementById('langSelector'); - if (langSelector) langSelector.value = activeLang; - - // rest of standard init... - } - ``` -* Listen to Settings change event: - ```javascript - const langSelector = document.getElementById('langSelector'); - if (langSelector) { - langSelector.addEventListener('change', async () => { - const selectedLang = langSelector.value; - await chrome.storage.sync.set({ locale: selectedLang }); - await loadLocale(selectedLang); - translateDOM(); - // Re-render empty elements and tab list using new dynamic strings - refreshLogs(); - refreshHistory(); - populateTabs(); - }); - } - ``` - -### 4. Background Notifications (`background.js`) -* Notifications inside `showNotification` should fetch dynamic keys based on `chrome.storage.sync` language settings and build clean alerts dynamically using `chrome.storage.sync.get('locale')`. -* Ensure that WebSocket event transmissions and video player scripts in `content.js` remain **completely untouched and unaware** of the localization engine. - ---- - -## πŸ”’ Safety Guardrail - -* **WebSocket Engine Integrity:** Under no circumstances should `background.js` Socket.IO handshakes, rate limits, or binary protocol headers be adjusted. i18n is strictly an interface rendering skin layer. -* **Player Control Pipeline Integrity:** `content.js` expectedEvent suppression tables, HLS buffer calculations, and Media Session API listeners must remain untouched. Do not bind any i18n logic into the content script's active tracking loop. - ---- - -## πŸ§ͺ Verification Tasks - -1. **Autodetection Audit:** Force-load the extension in Chrome/Firefox in a non-English language container and ensure it starts in that language or English gracefully. -2. **Integrity Validation Script:** Write a sanity node checker script `/scripts/test-locales.js` to ensure all key structures are uniform across all JSON files. -3. **Real-Time Refresh Verification:** Change dynamic drop-down preferences and verify that every element and alert swaps languages cleanly with zero redraw glitches or page crashes. diff --git a/website/assets/NewLogoIcon_64.webp b/website/assets/NewLogoIcon_64.webp index b1f4e43..660ffe2 100644 Binary files a/website/assets/NewLogoIcon_64.webp and b/website/assets/NewLogoIcon_64.webp differ