54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
import { useEffect } from 'preact/hooks';
|
|
import { effect } from '@preact/signals';
|
|
import { theme, initializeApp } from './state';
|
|
import { Shell } from './components/layout/Shell';
|
|
import { CommandPalette } from './components/shared/CommandPalette';
|
|
import { ToastContainer } from './components/shared/Toast';
|
|
import { ErrorBoundary } from './components/shared/ErrorBoundary';
|
|
import { useKeyboardShortcuts } from './hooks/useKeyboard';
|
|
|
|
export function App() {
|
|
// Enable global keyboard shortcuts
|
|
useKeyboardShortcuts();
|
|
useEffect(() => {
|
|
// Initialize app state
|
|
initializeApp();
|
|
|
|
// Apply theme reactively when signal changes
|
|
const dispose = effect(() => {
|
|
const root = document.documentElement;
|
|
const currentTheme = theme.value;
|
|
|
|
if (currentTheme === 'auto') {
|
|
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
root.dataset.theme = prefersDark ? 'dark' : 'light';
|
|
} else {
|
|
root.dataset.theme = currentTheme;
|
|
}
|
|
});
|
|
|
|
// Listen for system theme changes (for auto mode)
|
|
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
const handleSystemChange = () => {
|
|
if (theme.value === 'auto') {
|
|
const root = document.documentElement;
|
|
root.dataset.theme = mediaQuery.matches ? 'dark' : 'light';
|
|
}
|
|
};
|
|
mediaQuery.addEventListener('change', handleSystemChange);
|
|
|
|
return () => {
|
|
dispose();
|
|
mediaQuery.removeEventListener('change', handleSystemChange);
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<ErrorBoundary>
|
|
<Shell />
|
|
<CommandPalette />
|
|
<ToastContainer />
|
|
</ErrorBoundary>
|
|
);
|
|
}
|