151 lines
4.9 KiB
TypeScript
151 lines
4.9 KiB
TypeScript
import { useEffect, useLayoutEffect, useState } from 'react';
|
|
import type { ThemeMode } from './components/AppSettingsWindow';
|
|
import CanvasStudio from './pages/CanvasStudio';
|
|
import FindPage from './pages/FindPage';
|
|
import HelpPage from './pages/HelpPage';
|
|
import OrdersPage from './pages/OrdersPage';
|
|
import TemplateHome from './pages/TemplateHome';
|
|
import TestWorkbench from './pages/TestWorkbench';
|
|
import { CanvasDocument, WordcloudReplaceSession, WordcloudStickerPayload } from './types';
|
|
import { createDefaultDocument } from './lib/canvasDocument';
|
|
|
|
type AppPage = 'home' | 'canvas' | 'wordcloud' | 'orders' | 'find' | 'help';
|
|
|
|
const getStoredTheme = (): ThemeMode => {
|
|
const stored = window.localStorage.getItem('wordcloud-theme');
|
|
return stored === 'light' || stored === 'dark' || stored === 'system' ? stored : 'system';
|
|
};
|
|
|
|
const getSystemTheme = () =>
|
|
window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
|
|
export default function App() {
|
|
const [page, setPage] = useState<AppPage>('home');
|
|
const [themeMode, setThemeMode] = useState<ThemeMode>(getStoredTheme);
|
|
const [systemTheme, setSystemTheme] = useState<'light' | 'dark'>(getSystemTheme);
|
|
const [initialDocument, setInitialDocument] = useState<CanvasDocument | null>(null);
|
|
const [pendingWordcloudSticker, setPendingWordcloudSticker] = useState<WordcloudStickerPayload | null>(null);
|
|
const [pendingReplaceSession, setPendingReplaceSession] = useState<WordcloudReplaceSession | null>(null);
|
|
|
|
const openHelp = () => setPage('help');
|
|
|
|
useLayoutEffect(() => {
|
|
const resolvedTheme = themeMode === 'system' ? systemTheme : themeMode;
|
|
document.documentElement.dataset.theme = resolvedTheme;
|
|
document.documentElement.dataset.themeMode = themeMode;
|
|
document.documentElement.style.colorScheme = resolvedTheme;
|
|
window.localStorage.setItem('wordcloud-theme', themeMode);
|
|
}, [themeMode, systemTheme]);
|
|
|
|
useEffect(() => {
|
|
const media = window.matchMedia('(prefers-color-scheme: dark)');
|
|
const handleChange = (event: MediaQueryListEvent) => {
|
|
setSystemTheme(event.matches ? 'dark' : 'light');
|
|
};
|
|
|
|
setSystemTheme(media.matches ? 'dark' : 'light');
|
|
media.addEventListener('change', handleChange);
|
|
return () => media.removeEventListener('change', handleChange);
|
|
}, []);
|
|
|
|
if (page === 'wordcloud') {
|
|
return (
|
|
<TestWorkbench
|
|
themeMode={themeMode}
|
|
systemTheme={systemTheme}
|
|
onThemeModeChange={setThemeMode}
|
|
onOpenCanvas={() => setPage('canvas')}
|
|
onOpenHome={() => setPage('home')}
|
|
onOpenHelp={openHelp}
|
|
replaceSession={pendingReplaceSession}
|
|
onConsumeReplaceSession={() => setPendingReplaceSession(null)}
|
|
onImportWordcloudSticker={(payload) => {
|
|
setPendingWordcloudSticker(payload);
|
|
setPendingReplaceSession(null);
|
|
setPage('canvas');
|
|
}}
|
|
/>
|
|
);
|
|
}
|
|
|
|
if (page === 'canvas') {
|
|
return (
|
|
<CanvasStudio
|
|
themeMode={themeMode}
|
|
systemTheme={systemTheme}
|
|
onThemeModeChange={setThemeMode}
|
|
onOpenHome={() => setPage('home')}
|
|
onOpenWordcloud={() => {
|
|
setPendingReplaceSession(null);
|
|
setPage('wordcloud');
|
|
}}
|
|
onOpenHelp={openHelp}
|
|
onReplaceWordcloudNames={(session) => {
|
|
setPendingReplaceSession(session);
|
|
setPage('wordcloud');
|
|
}}
|
|
initialDocument={initialDocument}
|
|
onConsumeInitialDocument={() => setInitialDocument(null)}
|
|
pendingWordcloudSticker={pendingWordcloudSticker}
|
|
onConsumeWordcloudSticker={() => setPendingWordcloudSticker(null)}
|
|
/>
|
|
);
|
|
}
|
|
|
|
if (page === 'help') {
|
|
return (
|
|
<HelpPage
|
|
themeMode={themeMode}
|
|
systemTheme={systemTheme}
|
|
onThemeModeChange={setThemeMode}
|
|
onOpenHome={() => setPage('home')}
|
|
onOpenCanvas={() => setPage('canvas')}
|
|
onOpenWordcloud={() => setPage('wordcloud')}
|
|
onOpenOrders={() => setPage('orders')}
|
|
onOpenFind={() => setPage('find')}
|
|
/>
|
|
);
|
|
}
|
|
|
|
if (page === 'orders') {
|
|
return (
|
|
<OrdersPage
|
|
themeMode={themeMode}
|
|
systemTheme={systemTheme}
|
|
onThemeModeChange={setThemeMode}
|
|
onOpenHome={() => setPage('home')}
|
|
/>
|
|
);
|
|
}
|
|
|
|
if (page === 'find') {
|
|
return (
|
|
<FindPage
|
|
themeMode={themeMode}
|
|
systemTheme={systemTheme}
|
|
onThemeModeChange={setThemeMode}
|
|
onOpenHome={() => setPage('home')}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<TemplateHome
|
|
themeMode={themeMode}
|
|
systemTheme={systemTheme}
|
|
onThemeModeChange={setThemeMode}
|
|
onCreateBlank={() => {
|
|
setInitialDocument(createDefaultDocument());
|
|
setPage('canvas');
|
|
}}
|
|
onUseTemplate={(template) => {
|
|
setInitialDocument(template.document);
|
|
setPage('canvas');
|
|
}}
|
|
onOpenOrders={() => setPage('orders')}
|
|
onOpenFind={() => setPage('find')}
|
|
onOpenHelp={openHelp}
|
|
/>
|
|
);
|
|
}
|