Massive AI Overhaul
This commit is contained in:
121
theme-manager.js
Normal file
121
theme-manager.js
Normal file
@@ -0,0 +1,121 @@
|
||||
(function(global) {
|
||||
'use strict';
|
||||
|
||||
const THEME_STORAGE_KEY = 'svs-theme';
|
||||
const THEME_STYLESHEET_ID = 'themeStylesheetLink';
|
||||
const THEME_ASSET_VERSION = '20260313-02';
|
||||
const SVG_SUN = '<span class="fa-icon fa-icon-sun-bright fa-icon--theme" style="--icon-size:17px;"></span>';
|
||||
const SVG_MOON = '<span class="fa-icon fa-icon-moon-stars fa-icon--theme" style="--icon-size:15px;"></span>';
|
||||
const SVG_GLASS = '<span class="fa-icon fa-icon-sparkles fa-icon--theme" style="--icon-size:16px;"></span>';
|
||||
const SVG_RETRO = '<span class="fa-icon fa-icon-tv-retro fa-icon--theme" style="--icon-size:16px;"></span>';
|
||||
const THEME_ORDER = ['dark', 'light', 'glass', '70retro'];
|
||||
const THEME_CONFIG = {
|
||||
dark: {
|
||||
icon: SVG_MOON,
|
||||
href: null,
|
||||
label: 'Dark'
|
||||
},
|
||||
light: {
|
||||
icon: SVG_SUN,
|
||||
href: 'SVS-MSP-Calculator-light.css',
|
||||
label: 'Light'
|
||||
},
|
||||
glass: {
|
||||
icon: SVG_GLASS,
|
||||
href: 'SVS-MSP-Calculator-glass.css',
|
||||
label: 'Glass'
|
||||
},
|
||||
'70retro': {
|
||||
icon: SVG_RETRO,
|
||||
href: 'SVS-MSP-Calculator-70retro.css',
|
||||
label: '70s Retro'
|
||||
}
|
||||
};
|
||||
|
||||
function getSavedTheme() {
|
||||
const saved = localStorage.getItem(THEME_STORAGE_KEY);
|
||||
return THEME_ORDER.includes(saved) ? saved : 'dark';
|
||||
}
|
||||
|
||||
function getCurrentTheme() {
|
||||
const applied = document.documentElement.dataset.theme;
|
||||
return THEME_ORDER.includes(applied) ? applied : getSavedTheme();
|
||||
}
|
||||
|
||||
function updateThemeToggleUi(theme) {
|
||||
const icon = document.getElementById('themeToggleIcon');
|
||||
const btn = document.getElementById('themeToggle');
|
||||
const currentIndex = THEME_ORDER.indexOf(theme);
|
||||
const nextTheme = THEME_ORDER[(currentIndex + 1) % THEME_ORDER.length];
|
||||
const currentLabel = THEME_CONFIG[theme].label;
|
||||
const nextLabel = THEME_CONFIG[nextTheme].label;
|
||||
|
||||
if (icon) icon.innerHTML = THEME_CONFIG[theme].icon;
|
||||
if (btn) {
|
||||
const uiLabel = `Theme: ${currentLabel}. Click to switch to ${nextLabel}.`;
|
||||
btn.setAttribute('title', uiLabel);
|
||||
btn.setAttribute('aria-label', uiLabel);
|
||||
}
|
||||
}
|
||||
|
||||
function applyTheme(theme) {
|
||||
const nextTheme = THEME_ORDER.includes(theme) ? theme : 'dark';
|
||||
const existing = document.getElementById(THEME_STYLESHEET_ID);
|
||||
const legacyLight = document.getElementById('lightThemeLink');
|
||||
|
||||
if (existing) existing.remove();
|
||||
if (legacyLight) legacyLight.remove();
|
||||
|
||||
const themeHref = THEME_CONFIG[nextTheme].href;
|
||||
if (themeHref) {
|
||||
const el = document.createElement('link');
|
||||
el.id = THEME_STYLESHEET_ID;
|
||||
el.rel = 'stylesheet';
|
||||
el.href = `${themeHref}?v=${THEME_ASSET_VERSION}`;
|
||||
el.dataset.theme = nextTheme;
|
||||
document.head.appendChild(el);
|
||||
}
|
||||
|
||||
document.documentElement.dataset.theme = nextTheme;
|
||||
localStorage.setItem(THEME_STORAGE_KEY, nextTheme);
|
||||
updateThemeToggleUi(nextTheme);
|
||||
}
|
||||
|
||||
function toggleTheme() {
|
||||
const currentTheme = getCurrentTheme();
|
||||
const currentIndex = THEME_ORDER.indexOf(currentTheme);
|
||||
const nextTheme = THEME_ORDER[(currentIndex + 1) % THEME_ORDER.length];
|
||||
|
||||
// Enable brief color transition for smooth theme swap
|
||||
document.body.classList.add('theme-transitioning');
|
||||
applyTheme(nextTheme);
|
||||
setTimeout(function() {
|
||||
document.body.classList.remove('theme-transitioning');
|
||||
}, 300);
|
||||
}
|
||||
|
||||
function initTheme() {
|
||||
applyTheme(getSavedTheme());
|
||||
}
|
||||
|
||||
global.SVSQuoteTheme = {
|
||||
THEME_STORAGE_KEY,
|
||||
THEME_STYLESHEET_ID,
|
||||
THEME_ASSET_VERSION,
|
||||
THEME_ORDER,
|
||||
THEME_CONFIG,
|
||||
getSavedTheme,
|
||||
getCurrentTheme,
|
||||
updateThemeToggleUi,
|
||||
applyTheme,
|
||||
toggleTheme,
|
||||
initTheme
|
||||
};
|
||||
|
||||
global.getSavedTheme = getSavedTheme;
|
||||
global.getCurrentTheme = getCurrentTheme;
|
||||
global.updateThemeToggleUi = updateThemeToggleUi;
|
||||
global.applyTheme = applyTheme;
|
||||
global.toggleTheme = toggleTheme;
|
||||
global.initTheme = initTheme;
|
||||
})(window);
|
||||
Reference in New Issue
Block a user