89 lines
3.8 KiB
JavaScript
89 lines
3.8 KiB
JavaScript
/* Mindflux Theme – Dark/Light-Umschaltung, zentral.
|
||
Im <head> einbinden (ohne defer), dann setzt es das Theme vor dem Rendern (kein Flash).
|
||
Jeder Button mit Klasse .mf-theme wird automatisch zum Umschalter. */
|
||
(function () {
|
||
var KEY = 'mf-theme';
|
||
function read() { try { return localStorage.getItem(KEY) || 'dark'; } catch (e) { return 'dark'; } }
|
||
function apply(mode) { document.documentElement.setAttribute('data-theme', mode); }
|
||
|
||
apply(read()); // früh -> kein Aufblitzen
|
||
|
||
// Globale, rein clientseitige Komfortfunktionen. FluxTimer bleibt auf öffentlichen
|
||
// Seiten inaktiv, läuft bei aktivierter Einstellung aber über Seitennavigationen weiter.
|
||
if (!document.querySelector('link[data-fluxtimer]')) {
|
||
var timerCss = document.createElement('link');
|
||
timerCss.rel = 'stylesheet';
|
||
timerCss.href = '/css/fluxtimer.css?v=3';
|
||
timerCss.setAttribute('data-fluxtimer', '');
|
||
document.head.appendChild(timerCss);
|
||
}
|
||
if (!document.querySelector('script[data-fluxtimer]')) {
|
||
var timerScript = document.createElement('script');
|
||
timerScript.src = '/js/fluxtimer.js?v=1';
|
||
timerScript.defer = true;
|
||
timerScript.setAttribute('data-fluxtimer', '');
|
||
document.head.appendChild(timerScript);
|
||
}
|
||
|
||
var SUN = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>';
|
||
var MOON = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>';
|
||
|
||
function paint() {
|
||
var dark = document.documentElement.getAttribute('data-theme') === 'dark';
|
||
document.querySelectorAll('.mf-theme').forEach(function (b) { b.innerHTML = dark ? SUN : MOON; });
|
||
}
|
||
function toggle() {
|
||
var next = document.documentElement.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
|
||
apply(next);
|
||
try { localStorage.setItem(KEY, next); } catch (e) {}
|
||
paint();
|
||
}
|
||
function set(mode) {
|
||
var next = mode === 'light' ? 'light' : 'dark';
|
||
apply(next);
|
||
try { localStorage.setItem(KEY, next); } catch (e) {}
|
||
paint();
|
||
}
|
||
window.MindfluxTheme = {
|
||
toggle: toggle,
|
||
apply: apply,
|
||
set: set,
|
||
current: function () { return document.documentElement.getAttribute('data-theme'); }
|
||
};
|
||
|
||
// Mobile-Nav: Off-Canvas-Drawer für Seiten mit App-Sidebar (.mf-shell)
|
||
function initMobileNav() {
|
||
var sidebar = document.querySelector('.mf-sidebar');
|
||
if (!sidebar || document.querySelector('.mf-burger')) return;
|
||
|
||
var burger = document.createElement('button');
|
||
burger.className = 'mf-burger';
|
||
burger.setAttribute('aria-label', 'Menü öffnen');
|
||
burger.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18M3 12h18M3 18h18"/></svg>';
|
||
|
||
var backdrop = document.createElement('div');
|
||
backdrop.className = 'mf-nav-backdrop';
|
||
|
||
function close() { document.body.classList.remove('mf-nav-open'); }
|
||
function toggleNav() { document.body.classList.toggle('mf-nav-open'); }
|
||
|
||
burger.addEventListener('click', toggleNav);
|
||
backdrop.addEventListener('click', close);
|
||
sidebar.querySelectorAll('a').forEach(function (a) { a.addEventListener('click', close); });
|
||
window.addEventListener('keydown', function (e) { if (e.key === 'Escape') close(); });
|
||
|
||
document.body.appendChild(backdrop);
|
||
document.body.appendChild(burger);
|
||
}
|
||
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
document.querySelectorAll('.mf-theme').forEach(function (b) {
|
||
b.setAttribute('role', 'button');
|
||
b.setAttribute('aria-label', 'Theme umschalten');
|
||
b.addEventListener('click', toggle);
|
||
});
|
||
paint();
|
||
initMobileNav();
|
||
});
|
||
})();
|