backend-server-v2/web/static/vendor/theme.js

63 lines
2.1 KiB
JavaScript

(function () {
var STORAGE_KEY = 'theme';
var isAuthenticated = !!window.__TC_IS_AUTHENTICATED;
var serverTheme = (window.__TC_SERVER_THEME || '').toLowerCase();
var hasStoredTheme = false;
function getPreferredTheme() {
var stored = localStorage.getItem(STORAGE_KEY);
hasStoredTheme = stored === 'dark' || stored === 'light';
if (hasStoredTheme) return stored;
if (serverTheme === 'dark' || serverTheme === 'light') return serverTheme;
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
function applyTheme(theme) {
var isDark = theme === 'dark';
document.documentElement.classList.toggle('dark', isDark);
var button = document.getElementById('themeToggle');
if (button) {
button.setAttribute('aria-pressed', isDark ? 'true' : 'false');
button.textContent = isDark ? 'Light mode' : 'Dark mode';
}
}
function persistTheme(theme) {
localStorage.setItem(STORAGE_KEY, theme);
hasStoredTheme = true;
}
function sendThemeToServer(theme) {
if (!isAuthenticated) return;
fetch('/preferences/theme', {
method: 'POST',
credentials: 'same-origin',
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
body: 'theme=' + encodeURIComponent(theme),
}).catch(function () {});
}
window.toggleTheme = function toggleTheme() {
var currentIsDark = document.documentElement.classList.contains('dark');
var nextTheme = currentIsDark ? 'light' : 'dark';
applyTheme(nextTheme);
persistTheme(nextTheme);
sendThemeToServer(nextTheme);
};
window.initThemeToggle = function initThemeToggle() {
applyTheme(document.documentElement.classList.contains('dark') ? 'dark' : 'light');
};
var initialTheme = getPreferredTheme();
applyTheme(initialTheme);
var mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
if (typeof mediaQuery.addEventListener === 'function') {
mediaQuery.addEventListener('change', function (event) {
if (hasStoredTheme) return;
applyTheme(event.matches ? 'dark' : 'light');
});
}
})();