You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 2af7e9b
Browse filesBrowse the repository at this point in the historyBrowse files
ADFA-4516 feat(dashboard): l10n parity with the app (6 locales) + de-hardcode client UI
Brings the device dashboard's localization up to the app's level and removes hardcoded
user-facing client strings.
- i18n hardening (dashboard.js): supported langs en/es/fr/hi/pt/ru (was es/en only),
fallback to en on missing locale/key, data-i18n-placeholder + data-i18n-title support,
and a window.t(key, fallback) helper for dynamically-rendered strings.
- De-hardcode: every user-facing static string in index/app_home/app_kiwix/app_books/
app_maps/sidebar/footer is keyed (data-i18n/-placeholder/-title); dynamic strings in the
inline JS + dashboard.js go through window.t. Server-emitted '[System]' terminal logs in
sockets/*.ts are intentionally left as English technical output (out of scope).
- Locales: en.js/es.js rewritten and fr/hi/pt/ru.js added — 106 keys, identical set across
all six (app strings reused where concepts matched).
- Parity test (test/lang-parity.test.ts) asserts every locale has exactly en's key set;
wired into 'npm test' (now 14 tests: 8 maps + 6 parity). typecheck stays green.
Known minor: two kiwix modal bodies wrap a <code> path; applyTranslations sets innerText
so the monospace styling flattens to plain text (the path text is preserved in every
locale). Cosmetic-only; to be refined in the dashboard UX ticket.
// If the locale file fails to load, fall back to English so the UI is never blank.
51
71
script.onload=applyTranslations;
72
+
script.onerror=()=>{
73
+
constfallback=document.createElement('script');
74
+
fallback.src='lang/en.js';
75
+
fallback.onload=applyTranslations;
76
+
document.head.appendChild(fallback);
77
+
};
52
78
document.head.appendChild(script);
53
79
};
54
80
@@ -170,7 +196,7 @@ function renderLocalBooks(books) {
170
196
container.innerHTML='';
171
197
172
198
if(books.length===0){
173
-
container.innerHTML='<div class="col-12 text-center text-secondary py-5">No local books found. Check the Top 100 tab!</div>';
199
+
container.innerHTML=`<div class="col-12 text-center text-secondary py-5">${window.t('books_no_local','No local books found. Check the Top 100 tab!')}</div>`;
174
200
return;
175
201
}
176
202
@@ -184,9 +210,9 @@ function renderLocalBooks(books) {
alert(`❌ The book download or upload failed.\n\nServer Reason: ${data.message}\n\nMake sure you are not logged in multiple tabs at once.`);
456
+
alert(`${window.t('books_error_alert','❌ The book download or upload failed.')}\n\n${window.t('books_error_reason','Server Reason:')}${data.message}\n\n${window.t('books_error_hint','Make sure you are not logged in multiple tabs at once.')}`);
0 commit comments