125 lines
4.3 KiB
JavaScript
125 lines
4.3 KiB
JavaScript
// Theme handling
|
|
(function() {
|
|
// Constants
|
|
const THEME_STORAGE_KEY = 'theme';
|
|
const DEFAULT_THEME = 'light';
|
|
const THEMES = {
|
|
LIGHT: 'light',
|
|
DARK: 'dark'
|
|
};
|
|
|
|
// Initialize theme immediately to prevent flash of wrong theme
|
|
initThemeEarly();
|
|
|
|
// Wait for components to be loaded before initializing the theme system
|
|
document.addEventListener('componentsLoaded', function() {
|
|
console.log('Components loaded, initializing theme system...');
|
|
initializeThemeSystem();
|
|
});
|
|
|
|
// Functions
|
|
function initThemeEarly() {
|
|
try {
|
|
const savedTheme = localStorage.getItem(THEME_STORAGE_KEY);
|
|
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
|
|
// Set initial theme
|
|
const initialTheme = savedTheme || (prefersDark ? THEMES.DARK : THEMES.LIGHT);
|
|
setTheme(initialTheme);
|
|
} catch (error) {
|
|
console.warn('Early theme initialization error:', error);
|
|
// Fallback to light theme
|
|
setTheme(DEFAULT_THEME);
|
|
}
|
|
}
|
|
|
|
function initializeThemeSystem() {
|
|
console.log('Theme system initializing...');
|
|
try {
|
|
// Set up theme toggle button
|
|
const themeToggle = document.querySelector('.theme-toggle');
|
|
console.log('Theme toggle button found:', themeToggle);
|
|
|
|
if (themeToggle) {
|
|
themeToggle.addEventListener('click', toggleTheme);
|
|
updateThemeIcon(getCurrentTheme());
|
|
console.log('Theme toggle event listener added');
|
|
}
|
|
|
|
// Set up system theme change listener
|
|
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
mediaQuery.addEventListener('change', handleSystemThemeChange);
|
|
|
|
// Ensure theme persists across page reloads
|
|
window.addEventListener('beforeunload', persistTheme);
|
|
} catch (error) {
|
|
console.warn('Theme system initialization error:', error);
|
|
}
|
|
}
|
|
|
|
function getCurrentTheme() {
|
|
return document.documentElement.getAttribute('data-theme') || DEFAULT_THEME;
|
|
}
|
|
|
|
function setTheme(theme) {
|
|
document.documentElement.setAttribute('data-theme', theme);
|
|
document.body.dataset.theme = theme; // Add theme to body for better SSR support
|
|
}
|
|
|
|
function toggleTheme() {
|
|
try {
|
|
const currentTheme = getCurrentTheme();
|
|
const newTheme = currentTheme === THEMES.DARK ? THEMES.LIGHT : THEMES.DARK;
|
|
|
|
console.log('Theme Toggle clicked!');
|
|
console.log('Current theme:', currentTheme);
|
|
console.log('New theme:', newTheme);
|
|
|
|
setTheme(newTheme);
|
|
localStorage.setItem(THEME_STORAGE_KEY, newTheme);
|
|
updateThemeIcon(newTheme);
|
|
} catch (error) {
|
|
console.warn('Theme toggle error:', error);
|
|
}
|
|
}
|
|
|
|
function updateThemeIcon(theme) {
|
|
try {
|
|
const themeToggle = document.querySelector('.theme-toggle');
|
|
if (themeToggle) {
|
|
// Ensure both icons exist
|
|
if (!themeToggle.querySelector('.fa-sun')) {
|
|
themeToggle.innerHTML = `
|
|
<i class="fas fa-sun"></i>
|
|
<i class="fas fa-moon"></i>
|
|
`;
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.warn('Theme icon update error:', error);
|
|
}
|
|
}
|
|
|
|
function handleSystemThemeChange(e) {
|
|
try {
|
|
// Only update theme if user hasn't set a preference
|
|
if (!localStorage.getItem(THEME_STORAGE_KEY)) {
|
|
const newTheme = e.matches ? THEMES.DARK : THEMES.LIGHT;
|
|
setTheme(newTheme);
|
|
updateThemeIcon(newTheme);
|
|
}
|
|
} catch (error) {
|
|
console.warn('System theme change handler error:', error);
|
|
}
|
|
}
|
|
|
|
function persistTheme() {
|
|
try {
|
|
const currentTheme = getCurrentTheme();
|
|
localStorage.setItem(THEME_STORAGE_KEY, currentTheme);
|
|
document.body.dataset.theme = currentTheme; // Ensure theme is set on body before unload
|
|
} catch (error) {
|
|
console.warn('Theme persistence error:', error);
|
|
}
|
|
}
|
|
})(); |