From 63dd0cc686e1cb775b749b705d7b2b6641eed4fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B6=9B?= Date: Thu, 26 Dec 2024 15:34:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0WASM=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E6=96=87=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 11 ++++--- src/ColorFunctionContext.tsx | 56 ++++++++++++++++++++++++++++++++++++ src/pages/SchemeDetail.tsx | 22 +++++++++++++- 3 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 src/ColorFunctionContext.tsx diff --git a/src/App.tsx b/src/App.tsx index 03b54f3..8922571 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,5 @@ import { createBrowserRouter, RouterProvider } from 'react-router-dom'; +import { ColorFunctionProvider } from './ColorFunctionContext'; import { Notifications } from './components/Notifications'; import { Home } from './pages/Home'; import { MainLayout } from './pages/MainLayout'; @@ -28,9 +29,11 @@ const routes = createBrowserRouter([ export function App() { return ( - - Color Lab - - + + + Color Lab + + + ); } diff --git a/src/ColorFunctionContext.tsx b/src/ColorFunctionContext.tsx new file mode 100644 index 0000000..eba7730 --- /dev/null +++ b/src/ColorFunctionContext.tsx @@ -0,0 +1,56 @@ +import { + createContext, + ReactNode, + useCallback, + useEffect, + useMemo, + useState, + useTransition, +} from 'react'; +import type * as Wasm from './pkg/color_module'; +import init from './pkg/color_module'; + +export const ColorFunctionContext = createContext<{ + colorFn: Wasm.InitOutput | null; + isLoading: boolean; + error: Error | null; +}>({ + colorFn: null, + isLoading: true, + error: null, +}); + +type WasmProviderProps = { + children?: ReactNode; +}; + +export function ColorFunctionProvider({ children }: WasmProviderProps) { + const [wasmInstance, setWasmInstance] = useState(null); + const [isPending, startTransition] = useTransition(); + const [error, setError] = useState(null); + + const loadWasm = useCallback(() => { + startTransition(async () => { + try { + const wasm = await init(); + setWasmInstance(wasm); + } catch (e) { + console.error('[Load WASM]', e); + setError(e); + } + }); + }, []); + const contextValue = useMemo( + () => ({ + colorFn: wasmInstance, + isLoading: isPending, + error, + }), + [wasmInstance, isPending, error], + ); + useEffect(() => { + loadWasm(); + }, []); + + return {children}; +} diff --git a/src/pages/SchemeDetail.tsx b/src/pages/SchemeDetail.tsx index b509597..e0be4a3 100644 --- a/src/pages/SchemeDetail.tsx +++ b/src/pages/SchemeDetail.tsx @@ -1,3 +1,23 @@ +import { isNil } from 'lodash-es'; +import { useEffect } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; +import { useScheme } from '../stores/schemes'; + export function SchemeDetail() { - return
; + const { id } = useParams(); + const scheme = useScheme(id); + const navigate = useNavigate(); + + useEffect(() => { + if (isNil(scheme)) { + navigate('../not-found'); + } + }, [scheme, navigate]); + + return ( +
+

{scheme?.name}

+

{scheme?.description}

+
+ ); }