Files
wordcloud/frontend/src/App.tsx
T
2026-07-04 02:40:45 +08:00

73 lines
2.5 KiB
TypeScript

import { useLayoutEffect, useState } from 'react';
import CanvasStudio from './pages/CanvasStudio';
import TemplateHome from './pages/TemplateHome';
import TestWorkbench from './pages/TestWorkbench';
import { CanvasDocument, WordcloudStickerPayload } from './types';
import { createDefaultDocument } from './lib/canvasDocument';
type AppPage = 'home' | 'canvas' | 'wordcloud';
type ThemeMode = 'light' | 'dark' | 'system';
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] = useState<ThemeMode>(getStoredTheme);
const [systemTheme] = useState<'light' | 'dark'>(getSystemTheme);
const [initialDocument, setInitialDocument] = useState<CanvasDocument | null>(null);
const [pendingWordcloudSticker, setPendingWordcloudSticker] = useState<WordcloudStickerPayload | null>(null);
useLayoutEffect(() => {
const resolvedTheme = themeMode === 'system' ? systemTheme : themeMode;
document.documentElement.dataset.theme = resolvedTheme;
document.documentElement.dataset.themeMode = themeMode;
document.documentElement.style.colorScheme = resolvedTheme;
}, [themeMode, systemTheme]);
if (page === 'wordcloud') {
return (
<TestWorkbench
onOpenCanvas={() => setPage('canvas')}
onImportWordcloudSticker={(payload) => {
setPendingWordcloudSticker(payload);
setPage('canvas');
}}
/>
);
}
if (page === 'canvas') {
return (
<CanvasStudio
onOpenHome={() => setPage('home')}
onOpenWordcloud={() => setPage('wordcloud')}
initialDocument={initialDocument}
onConsumeInitialDocument={() => setInitialDocument(null)}
pendingWordcloudSticker={pendingWordcloudSticker}
onConsumeWordcloudSticker={() => setPendingWordcloudSticker(null)}
/>
);
}
return (
<TemplateHome
onCreateBlank={() => {
setInitialDocument(createDefaultDocument());
setPage('canvas');
}}
onUseTemplate={(template) => {
setInitialDocument(template.document);
setPage('canvas');
}}
onOpenCanvas={() => setPage('canvas')}
onOpenWordcloud={() => setPage('wordcloud')}
/>
);
}