This commit is contained in:
2025-11-28 02:46:51 +01:00
parent 99ad78dbe4
commit aae6006656
4 changed files with 192 additions and 149 deletions

View File

@@ -1,5 +1,4 @@
// public/assets/js/lang.js
(function () {
// ---------------------------------------------
// 1) Basis-Config aus PHP (app_config.php)
@@ -7,25 +6,16 @@
const usbConfig = window.usbConfig || {};
const i18nConfig = usbConfig.i18n || {};
// Map: { de: {code, label, flag}, en: {...}, dk: {...}, ... }
// Map: { de: {code, label, flag}, en: {...}, ... }
const availableLangs = i18nConfig.available || {};
// Liste der unterstützten Sprachen als Codes
const supportedLangs = Object.keys(availableLangs);
// Sprache, die PHP in fileload.php ermittelt hat
let currentLang = (i18nConfig.current || usbConfig.lang || "en").toLowerCase();
// Wenn PHP eine Sprache setzt, die nicht in available ist, nimm erste verfügbare
if (!supportedLangs.includes(currentLang) && supportedLangs.length > 0) {
currentLang = supportedLangs[0];
}
// Fallback, wenn gar nichts da ist
if (!currentLang) {
currentLang = "en";
}
// Aktuelle Sprache (wird unten per getInitialLang() gesetzt)
let currentLang = "en";
// Translations-Map (geflacht)
let translations = {};
// ---------------------------------------------
@@ -68,13 +58,39 @@
}, text);
}
// ------------------------------------------------
// 4) Browsersprache erkennen (2-Buchstaben-Code)
// ------------------------------------------------
function detectBrowserLang() {
const nav = window.navigator || {};
const candidates = [];
if (Array.isArray(nav.languages)) {
candidates.push(...nav.languages);
}
if (typeof nav.language === "string") {
candidates.push(nav.language);
}
if (typeof nav.userLanguage === "string") {
candidates.push(nav.userLanguage);
}
for (const raw of candidates) {
const code = (raw || "").slice(0, 2).toLowerCase();
if (supportedLangs.includes(code)) {
return code;
}
}
return null;
}
// ---------------------------------------------
// 4) Initiale Sprache bestimmen
// 5) Initiale Sprache bestimmen
//
// Priorität:
// a) URL ?lang= (falls gültig und in available)
// b) PHP (usbConfig.i18n.current / usbConfig.lang)
// c) localStorage (falls gültig)
// a) URL ?lang= (falls gültig)
// b) localStorage (explizit gewählte Sprache)
// c) Browsersprache
// d) 'en', wenn vorhanden
// e) erste verfügbare Sprache
// ---------------------------------------------
@@ -87,22 +103,22 @@
return paramLang;
}
// b) Server-seitig ermittelte Sprache (inkl. HTTP_ACCEPT_LANGUAGE)
const serverLang = (i18nConfig.current || usbConfig.lang || "").toLowerCase();
if (serverLang && supportedLangs.includes(serverLang)) {
return serverLang;
}
// c) localStorage, falls gültig
// b) localStorage (vom User über Switcher gewählt)
const stored = (localStorage.getItem("usbcheck_lang") || "").toLowerCase();
if (stored) {
if (supportedLangs.includes(stored)) {
return stored;
}
// ungültigen alten Wert aufräumen
// Ungültigen alten Wert aufräumen
localStorage.removeItem("usbcheck_lang");
}
// c) Browsersprache
const browserLang = detectBrowserLang();
if (browserLang) {
return browserLang;
}
// d) Wenn 'en' existiert → nimm 'en'
if (supportedLangs.includes("en")) {
return "en";
@@ -118,7 +134,7 @@
}
// ---------------------------------------------
// 5) i18n JSON per Fetch laden
// 6) i18n JSON per Fetch laden
// ---------------------------------------------
async function loadLangFile(lang) {
const code = (lang || "").toLowerCase();
@@ -142,7 +158,7 @@
}
// ---------------------------------------------
// 6) Data-i18n-Texte einsetzen
// 7) Data-i18n-Texte einsetzen
// ---------------------------------------------
function applyTranslations() {
document.documentElement.setAttribute("lang", currentLang);
@@ -166,10 +182,7 @@
}
// ---------------------------------------------
// 7) Label + Flag im Button aktualisieren
//
// Nutzt ausschließlich availableLangs aus PHP:
// availableLangs[code] = { code, label, flag }
// 8) Label + Flag im Button aktualisieren
// ---------------------------------------------
function updateLangCurrentLabel(lang) {
const code = (lang || "").toLowerCase();
@@ -196,35 +209,32 @@
}
// ---------------------------------------------
// 8) Sprache setzen
// 9) Sprache setzen (via Switcher)
//
// - akzeptiert JEDE Sprache, die in availableLangs liegt
// - akzeptiert nur Sprachen aus availableLangs
// - speichert in localStorage
// - schreibt ?lang= in die URL
// - lädt Seite neu, damit PHP + JS synchron sind
// ---------------------------------------------
async function setLang(lang) {
function setLang(lang) {
const code = (lang || "").toLowerCase();
if (!supportedLangs.includes(code)) {
console.warn("Unsupported language:", code, supportedLangs);
return;
}
// URL-Parameter setzen
const url = new URL(window.location.href);
url.searchParams.set("lang", code);
localStorage.setItem("usbcheck_lang", code);
// komplette Seite neu laden,
// damit PHP (fileload.php) + Meta-Tags + JS-Konfig konsistent sind
window.location.href = url.toString();
}
// ---------------------------------------------
// 9) DOM Ready
// 10) DOM Ready
// ---------------------------------------------
document.addEventListener("DOMContentLoaded", async function () {
// Initiale Sprache (kombiniert aus URL, PHP, localStorage)
// Initiale Sprache (kombiniert aus URL, localStorage, Browser)
currentLang = getInitialLang();
updateLangCurrentLabel(currentLang);
@@ -263,33 +273,11 @@
if (btn) {
const lang = btn.getAttribute("data-lang");
if (lang) {
// Nur wenn data-lang gesetzt ist → JS-gesteuerter Wechsel
setLang(lang);
e.preventDefault();
}
}
});
// (Login / Avatar Dummy kann bleiben unverändert)
const loginButton = document.getElementById("loginButton");
const userAvatar = document.getElementById("userAvatar");
const avatarInitials = document.getElementById("avatarInitials");
if (loginButton && userAvatar) {
loginButton.addEventListener("click", function () {
loginButton.classList.add("hidden");
userAvatar.classList.remove("hidden");
if (avatarInitials && !avatarInitials.textContent.trim()) {
avatarInitials.textContent = "UC";
}
});
if (userAvatar) {
userAvatar.addEventListener("click", function () {
alert(
"Account-Menü Platzhalter hier später Profil/Logout etc. einbauen."
);
});
}
}
});
})();