Changeset 0.25.3 (#163)
This commit is contained in:
@@ -172,36 +172,39 @@ Object.assign(UI, {
|
||||
},
|
||||
|
||||
initAppearance() {
|
||||
// Load saved prefs on startup
|
||||
const prefs = JSON.parse(localStorage.getItem('cs-appearance') || '{}');
|
||||
UI.applyAppearance(prefs.scale || 100, prefs.msgFont || 14);
|
||||
UI.applyTheme(prefs.theme || 'system');
|
||||
// Theme and appearance are already applied by the universal init
|
||||
// in base.html (Theme.init() + UI.restoreAppearance()). This method
|
||||
// only wires up the settings UI controls.
|
||||
|
||||
// Live preview on slider change
|
||||
// Scale slider: show value live, but apply zoom only on release to avoid
|
||||
// jarring layout jumps mid-drag (zoom changes the layout viewport).
|
||||
const scaleEl = document.getElementById('settingsScale');
|
||||
const msgFontEl = document.getElementById('settingsMsgFont');
|
||||
if (scaleEl) scaleEl.addEventListener('input', () => {
|
||||
const v = parseInt(scaleEl.value);
|
||||
document.getElementById('scaleValue').textContent = v + '%';
|
||||
UI.applyAppearance(v, parseInt(msgFontEl?.value || 14));
|
||||
});
|
||||
if (msgFontEl) msgFontEl.addEventListener('input', () => {
|
||||
const v = parseInt(msgFontEl.value);
|
||||
document.getElementById('msgFontValue').textContent = v + 'px';
|
||||
UI.applyAppearance(parseInt(scaleEl?.value || 100), v);
|
||||
});
|
||||
if (scaleEl) {
|
||||
scaleEl.addEventListener('input', () => {
|
||||
document.getElementById('scaleValue').textContent = parseInt(scaleEl.value) + '%';
|
||||
});
|
||||
scaleEl.addEventListener('change', () => {
|
||||
UI.applyAppearance(parseInt(scaleEl.value), parseInt(msgFontEl?.value || 14));
|
||||
});
|
||||
}
|
||||
if (msgFontEl) {
|
||||
msgFontEl.addEventListener('input', () => {
|
||||
document.getElementById('msgFontValue').textContent = parseInt(msgFontEl.value) + 'px';
|
||||
});
|
||||
msgFontEl.addEventListener('change', () => {
|
||||
UI.applyAppearance(parseInt(scaleEl?.value || 100), parseInt(msgFontEl.value));
|
||||
});
|
||||
}
|
||||
|
||||
// Theme toggle buttons
|
||||
document.querySelectorAll('#themeToggle .toggle-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const theme = btn.dataset.theme;
|
||||
UI.applyTheme(theme);
|
||||
UI.applyTheme(theme); // delegates to Theme.set() — single source of truth
|
||||
document.querySelectorAll('#themeToggle .toggle-btn').forEach(b =>
|
||||
b.classList.toggle('active', b === btn)
|
||||
);
|
||||
const p = JSON.parse(localStorage.getItem('cs-appearance') || '{}');
|
||||
p.theme = theme;
|
||||
localStorage.setItem('cs-appearance', JSON.stringify(p));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -224,10 +227,12 @@ Object.assign(UI, {
|
||||
});
|
||||
|
||||
// System theme change listener (for "system" mode)
|
||||
// Note: Theme.set('system') registers its own listener, but this
|
||||
// additionally fires the theme.changed event for CM6 editors.
|
||||
UI._systemThemeQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
UI._systemThemeQuery.addEventListener('change', () => {
|
||||
const p = JSON.parse(localStorage.getItem('cs-appearance') || '{}');
|
||||
if (p.theme === 'system') UI.applyTheme('system');
|
||||
const mode = typeof Theme !== 'undefined' ? Theme.get() : 'system';
|
||||
if (mode === 'system') UI.applyTheme('system');
|
||||
});
|
||||
},
|
||||
|
||||
@@ -236,17 +241,21 @@ Object.assign(UI, {
|
||||
* @param {'light'|'dark'|'system'} mode
|
||||
*/
|
||||
applyTheme(mode) {
|
||||
let resolved = mode;
|
||||
if (mode === 'system') {
|
||||
resolved = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
}
|
||||
if (resolved === 'light') {
|
||||
document.documentElement.setAttribute('data-theme', 'light');
|
||||
// Delegate to Theme API which handles system-mode resolution and
|
||||
// listens for OS preference changes.
|
||||
if (typeof Theme !== 'undefined') {
|
||||
Theme.set(mode);
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
// Fallback if Theme not loaded — resolve manually
|
||||
let resolved = mode;
|
||||
if (mode === 'system') {
|
||||
resolved = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
}
|
||||
document.documentElement.setAttribute('data-theme', resolved);
|
||||
}
|
||||
// Publish event for CM6 editors and extensions
|
||||
if (typeof Events !== 'undefined' && Events.emit) {
|
||||
const resolved = typeof Theme !== 'undefined' ? Theme.resolved() : mode;
|
||||
Events.emit('theme.changed', { mode, resolved });
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user