feat: comprehensive i18n coverage — all static text + auto-translate toasts
Locale files expanded to 300+ keys covering all sections: - Header menu, sidebar, search, viewer, editor, AI toolbar - Config modal (all sections), help modal, dashboard, graph, mermaid - Context menus, offline UI, palette, auth, shares, backups - All toasts and confirmations Automatic data-i18n tagging in index.html (177 attributes) via Python script — handles all user-facing static text nodes. Zero concatenation errors verified. i18n.js: added tr() reverse-lookup function (French text → key → current locale translation) ui.js: showToast() now auto-translates via tr() — all 24 existing toast call sites benefit automatically
This commit is contained in:
@@ -51,6 +51,30 @@ export function t(key, params) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// ── Reverse-lookup cache (French text → key) ────────────────────────────
|
||||
let _reverseCache = null;
|
||||
|
||||
function _buildReverseCache() {
|
||||
_reverseCache = {};
|
||||
for (const [k, v] of Object.entries(_fallbackStrings)) {
|
||||
if (k.startsWith('_')) continue;
|
||||
// Prefer shorter keys when multiple keys map to the same French text
|
||||
if (!_reverseCache[v] || k.length < _reverseCache[v].length) {
|
||||
_reverseCache[v] = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Translate a French string to the current locale by reverse lookup.
|
||||
* "Paramètres client sauvegardés" → fr: same, en: "Client settings saved".
|
||||
* If the string is not found in the FR locale, returns it unchanged. */
|
||||
export function tr(frenchText) {
|
||||
if (!frenchText || _currentLocale === 'fr') return frenchText;
|
||||
if (!_reverseCache) _buildReverseCache();
|
||||
var key = _reverseCache[frenchText];
|
||||
return key ? t(key) : frenchText;
|
||||
}
|
||||
|
||||
/** Change locale and re-translate the entire DOM.
|
||||
* Persists to localStorage. */
|
||||
export async function setLocale(locale) {
|
||||
|
||||
+3
-1
@@ -6,6 +6,7 @@ import { safeCreateIcons, getFileIcon, escapeHtml } from './utils.js';
|
||||
import { syncActiveFileTreeItem, refreshSidebarTreePreservingState } from './sidebar.js';
|
||||
import { GraphViewManager } from './graph.js';
|
||||
import { DashboardConflictsWidget } from './dashboard.js';
|
||||
import { t, tr } from './i18n.js';
|
||||
// ---------------------------------------------------------------------------
|
||||
// Right Sidebar Manager
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -347,7 +348,8 @@ export function populateCustomDropdown(dropdownId, optionsList, defaultValue) {
|
||||
|
||||
/** Display a brief toast message at the bottom of the viewport. */
|
||||
export function showToast(message, type) {
|
||||
console.log("showToast called with:", message, type);
|
||||
// Auto-translate French messages via reverse lookup
|
||||
message = tr(message);
|
||||
type = type || "info";
|
||||
let container = document.getElementById("toast-container");
|
||||
if (!container) {
|
||||
|
||||
Reference in New Issue
Block a user