126 lines
4.2 KiB
JavaScript
126 lines
4.2 KiB
JavaScript
(function () {
|
|
'use strict';
|
|
|
|
// --- theme (dark/light), persisted per browser -------------------------
|
|
var THEME_KEY = 'ts3monolith-theme';
|
|
var root = document.documentElement;
|
|
var toggle = document.querySelector('.theme-toggle');
|
|
var graphs = document.querySelectorAll('.js-live-graph');
|
|
var openers = document.querySelectorAll('.js-graph-open');
|
|
|
|
function currentTheme() {
|
|
return root.getAttribute('data-theme') === 'light' ? 'light' : 'dark';
|
|
}
|
|
|
|
// RRD graphs are static PNGs rendered server-side in both a dark and a
|
|
// light palette (see internal/rrd/rrd.go); swap to the variant matching
|
|
// the active theme so panel graphs never clash with the page around them.
|
|
function applyGraphTheme(theme) {
|
|
var stamp = Date.now();
|
|
graphs.forEach(function (img) {
|
|
var src = theme === 'light' ? img.dataset.srcLight : img.dataset.src;
|
|
if (src) img.src = src + '?v=' + stamp;
|
|
});
|
|
openers.forEach(function (button) {
|
|
var full = theme === 'light' ? button.getAttribute('data-full-light') : button.getAttribute('data-full');
|
|
if (full) button.setAttribute('data-full-active', full);
|
|
});
|
|
}
|
|
|
|
function applyTheme(mode) {
|
|
if (mode === 'light') root.setAttribute('data-theme', 'light');
|
|
else root.removeAttribute('data-theme');
|
|
applyGraphTheme(mode === 'light' ? 'light' : 'dark');
|
|
}
|
|
try {
|
|
var saved = window.localStorage.getItem(THEME_KEY);
|
|
if (saved) applyTheme(saved);
|
|
else applyGraphTheme(currentTheme());
|
|
} catch (e) {
|
|
applyGraphTheme(currentTheme());
|
|
}
|
|
|
|
if (toggle) {
|
|
toggle.addEventListener('click', function () {
|
|
var next = currentTheme() === 'light' ? 'dark' : 'light';
|
|
applyTheme(next);
|
|
try { window.localStorage.setItem(THEME_KEY, next); } catch (e) { /* ignore */ }
|
|
});
|
|
}
|
|
|
|
// --- live stats + graph refresh -----------------------------------------
|
|
var count = document.getElementById('online-count');
|
|
var status = document.getElementById('refresh-status');
|
|
var progress = document.getElementById('route-progress');
|
|
|
|
function setBusy(busy) {
|
|
if (progress) progress.hidden = !busy;
|
|
}
|
|
|
|
function refresh() {
|
|
setBusy(true);
|
|
if (status) status.textContent = 'Odświeżanie…';
|
|
|
|
var done = Promise.resolve();
|
|
if (count) {
|
|
done = fetch('/stats/live', { cache: 'no-store' })
|
|
.then(function (response) {
|
|
if (!response.ok) throw new Error('stats');
|
|
return response.json();
|
|
})
|
|
.then(function (data) {
|
|
if (typeof data.current === 'number') count.textContent = String(data.current);
|
|
if (status) status.textContent = 'Dane aktualne';
|
|
})
|
|
.catch(function () {
|
|
if (status) status.textContent = 'Nie udało się odświeżyć';
|
|
});
|
|
}
|
|
|
|
applyGraphTheme(currentTheme());
|
|
|
|
done.then(function () { setBusy(false); });
|
|
}
|
|
|
|
if (count || graphs.length) {
|
|
window.setInterval(refresh, 60000);
|
|
}
|
|
|
|
// --- graph lightbox -------------------------------------------------------
|
|
var lightbox = document.getElementById('graph-lightbox');
|
|
var lightboxImage = document.getElementById('lightbox-image');
|
|
var openers = document.querySelectorAll('.js-graph-open');
|
|
var closeButtons = document.querySelectorAll('[data-lightbox-close]');
|
|
|
|
function openLightbox(src) {
|
|
if (!lightbox || !lightboxImage) return;
|
|
lightboxImage.src = src + (src.indexOf('?') === -1 ? '?' : '&') + 'v=' + Date.now();
|
|
lightbox.hidden = false;
|
|
lightbox.setAttribute('aria-hidden', 'false');
|
|
document.body.classList.add('lightbox-open');
|
|
}
|
|
|
|
function closeLightbox() {
|
|
if (!lightbox || !lightboxImage) return;
|
|
lightbox.hidden = true;
|
|
lightbox.setAttribute('aria-hidden', 'true');
|
|
lightboxImage.src = '';
|
|
document.body.classList.remove('lightbox-open');
|
|
}
|
|
|
|
openers.forEach(function (button) {
|
|
button.addEventListener('click', function () {
|
|
var src = button.getAttribute('data-full-active') || button.getAttribute('data-full');
|
|
if (src) openLightbox(src);
|
|
});
|
|
});
|
|
|
|
closeButtons.forEach(function (button) {
|
|
button.addEventListener('click', closeLightbox);
|
|
});
|
|
|
|
document.addEventListener('keydown', function (event) {
|
|
if (event.key === 'Escape' && lightbox && !lightbox.hidden) closeLightbox();
|
|
});
|
|
})();
|