Files
P4RS3LT0NGV3/js/utils/theme.js
T

91 lines
2.6 KiB
JavaScript

/**
* Theme registry and application.
* Add entries to `themes` to expose new themes in the UI dropdown.
*/
window.ThemeUtils = {
defaultTheme: 'dark',
themes: [
{ id: 'dark', name: 'Dark', icon: 'fa-moon' },
{ id: 'light', name: 'Light', icon: 'fa-sun' },
{ id: 'accessible', name: 'Accessible', icon: 'fa-universal-access' },
{ id: 'bt6', name: 'BT6', icon: 'fa-shield-halved' },
{ id: 'pliny', name: 'Pliny', icon: 'fa-dragon' },
{ id: 'cyberpunk', name: 'Cyberpunk', icon: 'fa-city' },
{ id: 'wildwest', name: 'Wild West', icon: 'fa-hat-cowboy' }
],
getThemes() {
return this.themes.slice();
},
isValidTheme(themeId) {
return this.themes.some(function(theme) {
return theme.id === themeId;
});
},
normalizeThemeId(themeId) {
if (this.isValidTheme(themeId)) {
return themeId;
}
return this.defaultTheme;
},
applyTheme(themeId) {
var resolved = this.normalizeThemeId(themeId);
var body = document.body;
this.themes.forEach(function(theme) {
body.classList.remove('theme-' + theme.id);
});
body.classList.remove('dark-theme', 'light-theme');
body.classList.add('theme-' + resolved);
// Legacy aliases used by a few rules / older saved state
if (resolved === 'light' || resolved === 'accessible') {
body.classList.add('light-theme');
} else {
body.classList.add('dark-theme');
}
try {
localStorage.setItem('theme', resolved);
} catch (e) {
console.warn('Failed to save theme preference:', e);
}
return resolved;
},
initializeTheme() {
try {
var saved = localStorage.getItem('theme');
if (saved) {
return this.normalizeThemeId(saved);
}
} catch (e) {
console.warn('Failed to load theme preference:', e);
}
return this.defaultTheme;
},
cycleTheme(currentThemeId) {
var current = this.normalizeThemeId(currentThemeId);
var index = this.themes.findIndex(function(theme) {
return theme.id === current;
});
if (index === -1) {
index = 0;
}
var next = this.themes[(index + 1) % this.themes.length];
return this.applyTheme(next.id);
},
/** Apply saved theme before Vue mounts (call from inline script in index). */
applyInitialTheme() {
return this.applyTheme(this.initializeTheme());
}
};