|
|
| import { useEffect } from 'react'; |
| import { useConfigStore } from '../../stores/useConfigStore'; |
| import { getCurrentWindow } from '@tauri-apps/api/window'; |
|
|
| import { isLinux } from '../../utils/env'; |
|
|
| export default function ThemeManager() { |
| const { config, loadConfig } = useConfigStore(); |
|
|
| |
| useEffect(() => { |
| const init = async () => { |
| await loadConfig(); |
| |
| setTimeout(async () => { |
| if (typeof window !== 'undefined' && (window as any).__TAURI_INTERNALS__) { |
| await getCurrentWindow().show(); |
| } |
| }, 100); |
| }; |
| init(); |
| }, [loadConfig]); |
|
|
| |
| useEffect(() => { |
| if (!config) return; |
|
|
| const applyTheme = async (theme: string) => { |
| const root = document.documentElement; |
| const isDark = theme === 'dark'; |
|
|
| |
| |
| try { |
| if (!isLinux() && (window as any).__TAURI_INTERNALS__) { |
| const bgColor = isDark ? '#1d232a' : '#FAFBFC'; |
| |
| getCurrentWindow().setBackgroundColor(bgColor).catch(e => |
| console.error('Failed to set window background color:', e) |
| ); |
|
|
| |
| const { invoke } = await import('@tauri-apps/api/core'); |
| invoke('set_window_theme', { theme }).catch(() => { |
| |
| }); |
| } |
| } catch (e) { |
| console.error('Window background sync failed:', e); |
| } |
|
|
| |
| root.setAttribute('data-theme', theme); |
|
|
| |
| root.style.backgroundColor = isDark ? '#1d232a' : '#FAFBFC'; |
|
|
| |
| if (isDark) { |
| root.classList.add('dark'); |
| } else { |
| root.classList.remove('dark'); |
| } |
| }; |
|
|
| const theme = config.theme || 'system'; |
|
|
| |
| localStorage.setItem('app-theme-preference', theme); |
|
|
| if (theme === 'system') { |
| const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); |
|
|
| const handleSystemChange = (e: MediaQueryListEvent | MediaQueryList) => { |
| const systemTheme = e.matches ? 'dark' : 'light'; |
| applyTheme(systemTheme); |
| }; |
|
|
| |
| handleSystemChange(mediaQuery); |
|
|
| |
| mediaQuery.addEventListener('change', handleSystemChange); |
| return () => mediaQuery.removeEventListener('change', handleSystemChange); |
| } else { |
| applyTheme(theme); |
| } |
| }, [config?.theme]); |
|
|
| return null; |
| } |
|
|