mirror of
https://github.com/elder-plinius/P4RS3LT0NGV3.git
synced 2026-07-12 15:36:32 +02:00
91 lines
2.6 KiB
JavaScript
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());
|
|
}
|
|
};
|