SIDEL_ScriptsManager/app/static/js/theme-manager.js

239 lines
7.9 KiB
JavaScript

// Theme management functionality
class ThemeManager {
constructor() {
this.currentTheme = this.getStoredTheme() || this.getPreferredTheme();
this.init();
}
init() {
this.applyTheme(this.currentTheme);
this.setupEventListeners();
}
getStoredTheme() {
return localStorage.getItem('theme');
}
setStoredTheme(theme) {
localStorage.setItem('theme', theme);
}
getPreferredTheme() {
if (this.getStoredTheme()) {
return this.getStoredTheme();
}
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
applyTheme(theme) {
document.body.className = document.body.className.replace(/theme-\w+/, '');
document.body.classList.add(`theme-${theme}`);
this.currentTheme = theme;
this.setStoredTheme(theme);
// Update theme toggle button
this.updateThemeToggleButton();
// Dispatch theme change event
window.dispatchEvent(new CustomEvent('themeChanged', {
detail: { theme: theme }
}));
}
toggleTheme() {
const newTheme = this.currentTheme === 'light' ? 'dark' : 'light';
this.applyTheme(newTheme);
// Update user preference via API if logged in
if (typeof ScriptsManager !== 'undefined') {
ScriptsManager.updateUserPreferences({ theme: newTheme })
.catch(error => console.error('Failed to update theme preference:', error));
}
}
updateThemeToggleButton() {
const toggleButton = document.getElementById('theme-toggle');
if (!toggleButton) return;
const darkIcon = toggleButton.querySelector('.theme-icon-dark');
const lightIcon = toggleButton.querySelector('.theme-icon-light');
if (this.currentTheme === 'dark') {
if (darkIcon) darkIcon.style.display = 'none';
if (lightIcon) lightIcon.style.display = 'inline';
} else {
if (darkIcon) darkIcon.style.display = 'inline';
if (lightIcon) lightIcon.style.display = 'none';
}
}
setupEventListeners() {
// Theme toggle button
const toggleButton = document.getElementById('theme-toggle');
if (toggleButton) {
toggleButton.addEventListener('click', () => this.toggleTheme());
}
// Listen for system theme changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (!this.getStoredTheme()) {
this.applyTheme(e.matches ? 'dark' : 'light');
}
});
// Listen for custom theme change events
window.addEventListener('setTheme', (e) => {
this.applyTheme(e.detail.theme);
});
}
getCurrentTheme() {
return this.currentTheme;
}
setTheme(theme) {
if (['light', 'dark'].includes(theme)) {
this.applyTheme(theme);
}
}
}
// Theme-specific component adjustments
class ThemeComponentManager {
constructor(themeManager) {
this.themeManager = themeManager;
this.init();
}
init() {
// Listen for theme changes
window.addEventListener('themeChanged', (e) => {
this.adjustComponents(e.detail.theme);
});
// Initial adjustment
this.adjustComponents(this.themeManager.getCurrentTheme());
}
adjustComponents(theme) {
this.adjustBootstrapComponents(theme);
this.adjustCustomComponents(theme);
this.adjustCharts(theme);
}
adjustBootstrapComponents(theme) {
// Adjust modal backdrop
const modals = document.querySelectorAll('.modal');
modals.forEach(modal => {
if (theme === 'dark') {
modal.classList.add('modal-dark');
} else {
modal.classList.remove('modal-dark');
}
});
// Adjust tooltips
const tooltips = document.querySelectorAll('.tooltip');
tooltips.forEach(tooltip => {
if (theme === 'dark') {
tooltip.classList.add('tooltip-dark');
} else {
tooltip.classList.remove('tooltip-dark');
}
});
}
adjustCustomComponents(theme) {
// Adjust log containers
const logContainers = document.querySelectorAll('.log-container');
logContainers.forEach(container => {
if (theme === 'dark') {
container.style.backgroundColor = '#000000';
container.style.color = '#ffffff';
} else {
container.style.backgroundColor = '#f8f9fa';
container.style.color = '#212529';
}
});
// Adjust code blocks
const codeBlocks = document.querySelectorAll('.code-block');
codeBlocks.forEach(block => {
if (theme === 'dark') {
block.style.backgroundColor = '#2d2d2d';
block.style.color = '#e9ecef';
block.style.borderColor = '#495057';
} else {
block.style.backgroundColor = '#f8f9fa';
block.style.color = '#212529';
block.style.borderColor = '#e9ecef';
}
});
}
adjustCharts(theme) {
// Adjust any charts or graphs based on theme
// This would be implemented when charts are added
const chartContainers = document.querySelectorAll('.chart-container');
chartContainers.forEach(container => {
const event = new CustomEvent('themeChanged', {
detail: { theme: theme }
});
container.dispatchEvent(event);
});
}
}
// Utility functions for theme-aware styling
function getThemeAwareColor(lightColor, darkColor) {
const theme = window.themeManager ? window.themeManager.getCurrentTheme() : 'light';
return theme === 'dark' ? darkColor : lightColor;
}
function getThemeAwareCSS(lightCSS, darkCSS) {
const theme = window.themeManager ? window.themeManager.getCurrentTheme() : 'light';
return theme === 'dark' ? darkCSS : lightCSS;
}
// CSS custom properties for theme-aware components
function updateThemeCustomProperties(theme) {
const root = document.documentElement;
if (theme === 'dark') {
root.style.setProperty('--theme-bg', '#1a1a1a');
root.style.setProperty('--theme-fg', '#e9ecef');
root.style.setProperty('--theme-border', '#495057');
root.style.setProperty('--theme-muted', '#adb5bd');
root.style.setProperty('--theme-card-bg', '#2d2d2d');
} else {
root.style.setProperty('--theme-bg', '#ffffff');
root.style.setProperty('--theme-fg', '#212529');
root.style.setProperty('--theme-border', '#dee2e6');
root.style.setProperty('--theme-muted', '#6c757d');
root.style.setProperty('--theme-card-bg', '#ffffff');
}
}
// Initialize theme management when DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
// Create global theme manager instance
window.themeManager = new ThemeManager();
window.themeComponentManager = new ThemeComponentManager(window.themeManager);
// Update CSS custom properties
window.addEventListener('themeChanged', (e) => {
updateThemeCustomProperties(e.detail.theme);
});
// Initial update
updateThemeCustomProperties(window.themeManager.getCurrentTheme());
});
// Export for use in other modules
window.ThemeManager = {
getThemeAwareColor,
getThemeAwareCSS,
updateThemeCustomProperties
};