63 lines
2.1 KiB
JavaScript
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');
|
|
});
|
|
}
|
|
})();
|