mirror of
https://github.com/StuffAnThings/qbit_manage.git
synced 2025-10-11 22:36:35 +08:00
# Requirements Updated - fastapi==0.116.0 - retrying==1.4.0 - uvicorn==0.35.0 # New Features - **Web UI**: Introduced a new Web UI for configuring and managing qBit Manage. - Visual Configuration Editor for YAML files. - Command Execution directly from the UI. - Undo/Redo History for changes. - Theme Support (light/dark mode). - Responsive Design for desktop and mobile. - Real-time YAML Preview. - Pass skip qbitorrent check as optional parameter to the API (Adds #860)\ **Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.4.0...v4.5.0 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: ineednewpajamas <73252768+ineednewpajamas@users.noreply.github.com>
114 lines
2.8 KiB
JavaScript
114 lines
2.8 KiB
JavaScript
/**
|
|
* Theme Manager - Handles dark/light theme switching
|
|
*/
|
|
|
|
class ThemeManager {
|
|
constructor() {
|
|
this.currentTheme = this.getStoredTheme() || 'light';
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
// Apply the current theme
|
|
this.applyTheme(this.currentTheme);
|
|
|
|
// Set up theme toggle button
|
|
this.setupThemeToggle();
|
|
|
|
// Listen for system theme changes
|
|
this.setupSystemThemeListener();
|
|
}
|
|
|
|
getSystemTheme() {
|
|
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
}
|
|
|
|
getStoredTheme() {
|
|
return localStorage.getItem('qbit-manage-theme');
|
|
}
|
|
|
|
storeTheme(theme) {
|
|
localStorage.setItem('qbit-manage-theme', theme);
|
|
}
|
|
|
|
applyTheme(theme) {
|
|
const root = document.documentElement;
|
|
|
|
// Remove existing theme attributes
|
|
root.removeAttribute('data-theme');
|
|
|
|
if (theme === 'dark') {
|
|
root.setAttribute('data-theme', 'dark');
|
|
} else if (theme === 'light') {
|
|
root.setAttribute('data-theme', 'light');
|
|
}
|
|
// If theme is 'auto' or not set, let CSS handle it via prefers-color-scheme
|
|
|
|
this.currentTheme = theme;
|
|
this.updateThemeToggleIcon();
|
|
}
|
|
|
|
toggleTheme() {
|
|
const newTheme = this.currentTheme === 'light' ? 'dark' : 'light';
|
|
this.applyTheme(newTheme);
|
|
this.storeTheme(newTheme);
|
|
}
|
|
|
|
setupThemeToggle() {
|
|
const themeToggle = document.getElementById('theme-toggle');
|
|
if (themeToggle) {
|
|
themeToggle.addEventListener('click', () => {
|
|
this.toggleTheme();
|
|
});
|
|
}
|
|
}
|
|
|
|
updateThemeToggleIcon() {
|
|
const themeToggle = document.getElementById('theme-toggle');
|
|
if (!themeToggle) return;
|
|
|
|
const sunIcon = themeToggle.querySelector('.icon-sun');
|
|
const moonIcon = themeToggle.querySelector('.icon-moon');
|
|
|
|
if (!sunIcon || !moonIcon) return;
|
|
|
|
// Update title based on current theme
|
|
const title = this.currentTheme === 'light' ? 'Switch to Dark Mode' : 'Switch to Light Mode';
|
|
themeToggle.setAttribute('title', title);
|
|
|
|
// The CSS handles showing/hiding icons based on data-theme attribute
|
|
// No need to manually toggle visibility here
|
|
}
|
|
|
|
setupSystemThemeListener() {
|
|
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
mediaQuery.addEventListener('change', () => {
|
|
// Only react to system changes if we're in auto mode
|
|
if (!this.getStoredTheme()) {
|
|
this.updateThemeToggleIcon();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Public API
|
|
setTheme(theme) {
|
|
if (['light', 'dark'].includes(theme)) {
|
|
this.applyTheme(theme);
|
|
this.storeTheme(theme);
|
|
}
|
|
}
|
|
|
|
getCurrentTheme() {
|
|
return this.currentTheme;
|
|
}
|
|
|
|
getEffectiveTheme() {
|
|
return this.currentTheme;
|
|
}
|
|
}
|
|
|
|
// Create and export theme manager instance
|
|
export const themeManager = new ThemeManager();
|
|
|
|
// Also export the class for potential custom usage
|
|
export { ThemeManager };
|