mirror of
https://codeberg.org/Kankys/doxa.git
synced 2026-11-11 14:44:36 +01:00
new-doxa-monorepo
This commit is contained in:
1 parent
b4401527a3
commit
5eacbb0182
162 files changed
+21820
-2
No files matched your search
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"notes": []
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// Tento skript by měl být v HTML vložen PŘED hlavním script.js
|
||||
|
||||
// Globální překladová funkce, kterou bude používat i script.js
|
||||
let translations = {};
|
||||
window.t = (key, params = {}) => {
|
||||
let text = translations[key] || key;
|
||||
for (const p in params) {
|
||||
text = text.replace(`{${p}}`, params[p]);
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
||||
/**
|
||||
* Načte překlady pro daný jazyk a aplikuje je na DOM.
|
||||
* @param {string} lang - Kód jazyka (např. 'en', 'cs').
|
||||
*/
|
||||
window.setLanguage = async function(lang) {
|
||||
// 1. Uloží preferenci uživatele
|
||||
localStorage.setItem('doxa_lang', lang);
|
||||
|
||||
// Nastaví atribut 'lang' na <html> elementu
|
||||
document.documentElement.lang = lang;
|
||||
|
||||
// 2. Načte a uloží překlady
|
||||
try {
|
||||
const response = await fetch(`assets/locales/${lang}.json`);
|
||||
if (!response.ok) {
|
||||
console.error(`Chyba: Nepodařilo se načíst soubor s překlady: ${lang}.json`);
|
||||
translations = {};
|
||||
} else {
|
||||
translations = await response.json();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Chyba při načítání překladů pro jazyk ${lang}:`, error);
|
||||
translations = {};
|
||||
}
|
||||
|
||||
// 3. Přeloží všechny statické prvky v DOM
|
||||
document.querySelectorAll('[data-i18n-key]').forEach(el => {
|
||||
const key = el.getAttribute('data-i18n-key');
|
||||
const translation = window.t(key);
|
||||
|
||||
// Přeloží specifický atribut (např. placeholder, title), pokud je definován
|
||||
const attr = el.getAttribute('data-i18n-attr');
|
||||
if (attr) {
|
||||
el.setAttribute(attr, translation);
|
||||
} else {
|
||||
// Jinak přeloží obsah elementu
|
||||
el.innerHTML = translation;
|
||||
}
|
||||
});
|
||||
|
||||
// 4. DŮLEŽITÉ: Znovu inicializuje části aplikace, které používají dynamický text
|
||||
if (typeof window.updateDynamicUIText === 'function') {
|
||||
window.updateDynamicUIText();
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const userLang = localStorage.getItem('doxa_lang') || navigator.language.split('-')[0];
|
||||
const langToLoad = ['en', 'cs'].includes(userLang) ? userLang : 'cs';
|
||||
window.setLanguage(langToLoad);
|
||||
|
||||
const langToggleBtn = document.getElementById('langToggle');
|
||||
if (langToggleBtn) {
|
||||
langToggleBtn.addEventListener('click', () => {
|
||||
const currentLang = localStorage.getItem('doxa_lang') || 'cs';
|
||||
const nextLang = currentLang === 'cs' ? 'en' : 'cs';
|
||||
window.setLanguage(nextLang);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,85 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
const THEME_KEY = "doxa_theme";
|
||||
let systemMediaQuery = null;
|
||||
let systemMediaListener = null;
|
||||
|
||||
function applyTheme(theme) {
|
||||
try {
|
||||
if (systemMediaQuery && systemMediaListener) {
|
||||
try {
|
||||
if (systemMediaQuery.removeEventListener)
|
||||
systemMediaQuery.removeEventListener("change", systemMediaListener);
|
||||
else systemMediaQuery.removeListener(systemMediaListener);
|
||||
} catch (e) {}
|
||||
systemMediaQuery = null;
|
||||
systemMediaListener = null;
|
||||
}
|
||||
|
||||
if (theme === "dark") {
|
||||
document.body.classList.add("dark");
|
||||
} else if (theme === "light") {
|
||||
document.body.classList.remove("dark");
|
||||
} else {
|
||||
try {
|
||||
const mql = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
if (mql.matches) document.body.classList.add("dark");
|
||||
else document.body.classList.remove("dark");
|
||||
systemMediaQuery = mql;
|
||||
systemMediaListener = function (e) {
|
||||
if (e.matches) document.body.classList.add("dark");
|
||||
else document.body.classList.remove("dark");
|
||||
updateThemeButton();
|
||||
};
|
||||
if (mql.addEventListener)
|
||||
mql.addEventListener("change", systemMediaListener);
|
||||
else mql.addListener(systemMediaListener);
|
||||
} catch (e) {
|
||||
document.body.classList.remove("dark");
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
updateThemeButton();
|
||||
}
|
||||
|
||||
function updateThemeButton() {
|
||||
const btn = document.getElementById("themeToggle");
|
||||
if (!btn) return;
|
||||
const theme = getStoredTheme() || "system";
|
||||
let icon = "🌓";
|
||||
if (theme === "dark") {
|
||||
icon = "🌙";
|
||||
} else if (theme === "light") {
|
||||
icon = "☀️";
|
||||
}
|
||||
btn.textContent = icon;
|
||||
}
|
||||
|
||||
function getStoredTheme() {
|
||||
try {
|
||||
return localStorage.getItem(THEME_KEY);
|
||||
} catch (e) { return null; }
|
||||
}
|
||||
function setStoredTheme(value) {
|
||||
try {
|
||||
localStorage.setItem(THEME_KEY, value);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function toggleTheme() {
|
||||
const stored = getStoredTheme() || "system";
|
||||
const order = ["light", "dark", "system"];
|
||||
let idx = order.indexOf(stored);
|
||||
if (idx === -1) idx = 2;
|
||||
const next = order[(idx + 1) % order.length];
|
||||
setStoredTheme(next);
|
||||
applyTheme(next);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const themeBtn = document.getElementById("themeToggle");
|
||||
if (themeBtn) themeBtn.addEventListener("click", toggleTheme);
|
||||
applyTheme(getStoredTheme() || "system");
|
||||
});
|
||||
})();
|
||||
Reference in new issue
Block a user