Files
web7sys/public/js/theme.js
ben7sys 934aac41dc The dark/white mode functionality has been fixed for deployment with Coolify using Nixpacks. The improvements include:
Early theme initialization to prevent flashing
Proper component and script loading order
Enhanced error handling and fallbacks
Better theme state persistence
System theme preference detection
The theme system will now work correctly in the production environment when deployed through Coolify with Nixpacks build pack.
2024-11-15 10:15:18 +01:00

109 lines
3.7 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();
// Then initialize everything else when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initializeThemeSystem);
} else {
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);
document.documentElement.setAttribute('data-theme', initialTheme);
} catch (error) {
console.warn('Early theme initialization error:', error);
// Fallback to light theme
document.documentElement.setAttribute('data-theme', DEFAULT_THEME);
}
}
function initializeThemeSystem() {
try {
// Set up theme toggle button
const themeToggle = document.querySelector('.theme-toggle');
if (themeToggle) {
themeToggle.addEventListener('click', toggleTheme);
updateThemeIcon(getCurrentTheme());
}
// 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 toggleTheme() {
try {
const currentTheme = getCurrentTheme();
const newTheme = currentTheme === THEMES.DARK ? THEMES.LIGHT : THEMES.DARK;
document.documentElement.setAttribute('data-theme', newTheme);
localStorage.setItem(THEME_STORAGE_KEY, newTheme);
updateThemeIcon(newTheme);
} catch (error) {
console.warn('Theme toggle error:', error);
}
}
function updateThemeIcon(theme) {
try {
const themeIcon = document.querySelector('.theme-toggle i');
if (themeIcon) {
themeIcon.className = theme === THEMES.DARK
? 'fas fa-sun'
: 'fas fa-moon';
}
} 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;
document.documentElement.setAttribute('data-theme', 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);
} catch (error) {
console.warn('Theme persistence error:', error);
}
}
})();