feat(settings): theme scheduler, UI scale, CustomSelect scroll fix

- Time-based theme scheduler: auto-switches between day/night theme
  based on configurable times; setInterval re-checks every minute
- UI scale slider (80–150%) via CSS zoom on document root; preset
  buttons aligned to actual slider positions
- CustomSelect: scroll listener keeps dropdown anchored on scroll
- All features i18n in 7 languages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Psychotoxical
2026-04-08 12:23:14 +02:00
parent f0b423ddc4
commit e64d151079
16 changed files with 285 additions and 10 deletions
+10 -3
View File
@@ -61,6 +61,7 @@ import { useOfflineStore } from './store/offlineStore';
import { initHotCachePrefetch } from './hotCachePrefetch';
import { usePlayerStore, initAudioListeners } from './store/playerStore';
import { useThemeStore } from './store/themeStore';
import { useThemeScheduler } from './hooks/useThemeScheduler';
import { useFontStore } from './store/fontStore';
import { useEqStore } from './store/eqStore';
import { useKeybindingsStore } from './store/keybindingsStore';
@@ -504,18 +505,24 @@ function TauriEventBridge() {
}
export default function App() {
const theme = useThemeStore(s => s.theme);
useThemeStore(s => s.theme); // keep subscription so re-render on manual change
const effectiveTheme = useThemeScheduler();
const font = useFontStore(s => s.font);
const uiScale = useFontStore(s => s.uiScale);
const [exportPickerOpen, setExportPickerOpen] = useState(false);
useEffect(() => {
document.documentElement.setAttribute('data-theme', theme);
}, [theme]);
document.documentElement.setAttribute('data-theme', effectiveTheme);
}, [effectiveTheme]);
useEffect(() => {
document.documentElement.setAttribute('data-font', font);
}, [font]);
useEffect(() => {
document.documentElement.style.zoom = String(uiScale);
}, [uiScale]);
useEffect(() => {
return initAudioListeners();
}, []);