75 lines
2.5 KiB
JavaScript
75 lines
2.5 KiB
JavaScript
(function () {
|
|
'use strict';
|
|
|
|
function syncUI(surface) {
|
|
document.querySelectorAll('[data-theme-toggle]').forEach(function (btn) {
|
|
btn.setAttribute('aria-pressed', surface === 'ink' ? 'true' : 'false');
|
|
var icon = btn.querySelector('i');
|
|
if (icon) icon.className = surface === 'ink' ? 'bi bi-sun' : 'bi bi-moon';
|
|
});
|
|
}
|
|
|
|
function persistServerSide(surface) {
|
|
var body = new URLSearchParams({ surface: surface });
|
|
fetch('/Theme/Set', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
body: body.toString()
|
|
})
|
|
.then(function (r) {
|
|
console.log('[theme] POST /Theme/Set → ' + r.status + ' (surface=' + surface + ')');
|
|
})
|
|
.catch(function (err) {
|
|
console.warn('[theme] POST /Theme/Set failed', err);
|
|
});
|
|
}
|
|
|
|
function apply(surface) {
|
|
surface = (surface === 'ink') ? 'ink' : 'paper';
|
|
console.log('[theme] apply(' + surface + ')');
|
|
document.documentElement.setAttribute('data-surface', surface);
|
|
document.documentElement.setAttribute('data-bs-theme', surface === 'ink' ? 'dark' : 'light');
|
|
syncUI(surface);
|
|
persistServerSide(surface);
|
|
}
|
|
|
|
// Expose globally so Profile page radio and other pages can call it
|
|
window.pclApplyTheme = apply;
|
|
|
|
function bindToggles() {
|
|
document.querySelectorAll('[data-theme-toggle]').forEach(function (btn) {
|
|
// Remove any previously-bound handler to avoid doubles on re-bind
|
|
btn.removeEventListener('click', btn._pclToggleHandler);
|
|
btn._pclToggleHandler = function (e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
var current = document.documentElement.getAttribute('data-surface') || 'paper';
|
|
console.log('[theme] toggle clicked, current=' + current);
|
|
apply(current === 'ink' ? 'paper' : 'ink');
|
|
};
|
|
btn.addEventListener('click', btn._pclToggleHandler);
|
|
});
|
|
}
|
|
|
|
// Follow OS preference only when no cookie is set yet
|
|
if (window.matchMedia) {
|
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function (e) {
|
|
var hasCookie = document.cookie.indexOf('pcl_surface=') !== -1;
|
|
if (!hasCookie) apply(e.matches ? 'ink' : 'paper');
|
|
});
|
|
}
|
|
|
|
function onReady() {
|
|
var surface = document.documentElement.getAttribute('data-surface') || 'paper';
|
|
console.log('[theme] onReady, data-surface=' + surface);
|
|
syncUI(surface);
|
|
bindToggles();
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', onReady);
|
|
} else {
|
|
onReady();
|
|
}
|
|
})();
|