mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-20 00:41:14 +00:00
Translate all out-of-game UI (start screen, lobbies, etc.) (#316)
This PR adds full translation support for all out-of-game UI elements, including the start screen, public/private lobby modals, and other pre-game interfaces. All static text has been externalized to en.json and ja.json for future language support. If you find any spots that are not yet translated (missing from the JSON), please let me know. Thanks a lot! This is a follow-up to PR [#305](https://github.com/openfrontio/OpenFrontIO/pull/305). --------- Co-authored-by: Cldprv <dubois.cnm@tutanota.com> Co-authored-by: jacks0n <rosty.west89@gmail.com>
This commit is contained in:
co-authored by
Cldprv
jacks0n
parent
f188af6029
commit
9088adeb7a
+95
-1
@@ -304,7 +304,10 @@
|
||||
class="text-center appearance-none w-full bg-blue-100 hover:bg-blue-200 text-blue-900 p-3 sm:p-4 lg:p-5 font-medium text-sm sm:text-base lg:text-lg rounded-md border-none cursor-pointer transition-colors duration-300"
|
||||
>
|
||||
<option value="en">English</option>
|
||||
<option value="bg">Български</option>
|
||||
<option value="ja">日本語</option>
|
||||
<option value="fr">Français</option>
|
||||
<option value="nl">Nederlands</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -394,7 +397,98 @@
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script src="lang.js"></script>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", async function () {
|
||||
const locale = new Intl.Locale(navigator.language);
|
||||
const defaultLang = locale.language;
|
||||
const userLang = localStorage.getItem("lang") || defaultLang;
|
||||
async function loadLanguage(lang) {
|
||||
try {
|
||||
const response = await fetch(`/lang/${lang}.json`);
|
||||
if (!response.ok)
|
||||
throw new Error(`Language file not found: ${lang}`);
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error("🚨 Translation load error:", error);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
function applyTranslation(translations) {
|
||||
const components = [
|
||||
"single-player-modal",
|
||||
"host-lobby-modal",
|
||||
"join-private-lobby-modal",
|
||||
"emoji-table",
|
||||
"leader-board",
|
||||
"build-menu",
|
||||
"win-modal",
|
||||
"game-starting-modal",
|
||||
"top-bar",
|
||||
"player-panel",
|
||||
"help-modal",
|
||||
"username-input",
|
||||
"public-lobby",
|
||||
];
|
||||
|
||||
document.title = translations.main?.title || document.title;
|
||||
|
||||
document.querySelectorAll("[data-i18n]").forEach((element) => {
|
||||
const key = element.getAttribute("data-i18n");
|
||||
const keys = key.split(".");
|
||||
let text = translations;
|
||||
for (const k of keys) {
|
||||
text = text?.[k];
|
||||
if (!text) break;
|
||||
}
|
||||
if (!text && window.defaultTranslations) {
|
||||
let fallback = window.defaultTranslations;
|
||||
for (const k of keys) {
|
||||
fallback = fallback?.[k];
|
||||
if (!fallback) break;
|
||||
}
|
||||
text = fallback;
|
||||
}
|
||||
if (text) {
|
||||
element.innerHTML = text;
|
||||
} else {
|
||||
console.warn(`Missing translation key: ${key}`);
|
||||
}
|
||||
});
|
||||
components.forEach((tagName) => {
|
||||
const el = document.querySelector(tagName);
|
||||
if (el && typeof el.requestUpdate === "function") {
|
||||
el.requestUpdate();
|
||||
} else {
|
||||
console.warn(
|
||||
`requestUpdate() not available on <${tagName}> or element not found.`,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
async function changeLanguage(lang) {
|
||||
// console.log(`Changing language to: ${lang}`);
|
||||
localStorage.setItem("lang", lang);
|
||||
const translations = await loadLanguage(lang);
|
||||
window.translations = translations;
|
||||
applyTranslation(translations);
|
||||
}
|
||||
const defaultTranslations = await loadLanguage("en");
|
||||
window.defaultTranslations = defaultTranslations;
|
||||
const translations = await loadLanguage(userLang);
|
||||
window.translations = translations;
|
||||
applyTranslation(translations);
|
||||
|
||||
const langSelector = document.getElementById("lang-selector");
|
||||
if (langSelector) {
|
||||
langSelector.value = userLang;
|
||||
}
|
||||
document
|
||||
.getElementById("lang-selector")
|
||||
.addEventListener("change", function (event) {
|
||||
changeLanguage(event.target.value);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Analytics -->
|
||||
<script
|
||||
|
||||
Reference in New Issue
Block a user