From 2dce654ec4eca72eaecf2a3ae4cab30425781b1c Mon Sep 17 00:00:00 2001 From: ErikSin <67773827+ErikSin@users.noreply.github.com> Date: Mon, 16 Dec 2024 17:25:50 -0800 Subject: [PATCH 01/13] chore: add zustand --- package-lock.json | 33 ++++++++++++++++++++++++++++++++- package.json | 3 ++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe0f2f2..539c846 100644 --- a/package-lock.json +++ b/package-lock.json @@ -76,7 +76,8 @@ "typescript-eslint": "^8.15.0", "vite": "^5.4.11", "vite-plugin-svgr": "^4.3.0", - "vitest": "2.1.8" + "vitest": "2.1.8", + "zustand": "5.0.2" } }, "node_modules/@ampproject/remapping": { @@ -18572,6 +18573,36 @@ "funding": { "url": "https://github.com/sponsors/colinhacks" } + }, + "node_modules/zustand": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.2.tgz", + "integrity": "sha512-8qNdnJVJlHlrKXi50LDqqUNmUbuBjoKLrYQBnoChIbVph7vni+sY+YpvdjXG9YLd/Bxr6scMcR+rm5H3aSqPaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } } } } diff --git a/package.json b/package.json index d2f7a53..e5410da 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,8 @@ "typescript-eslint": "^8.15.0", "vite": "^5.4.11", "vite-plugin-svgr": "^4.3.0", - "vitest": "2.1.8" + "vitest": "2.1.8", + "zustand": "5.0.2" }, "overrides": { "better-sqlite3": "11.5.0" From b5e542cc2e5a2d0ce3618f9e97b03ee946b1f962 Mon Sep 17 00:00:00 2001 From: ErikSin <67773827+ErikSin@users.noreply.github.com> Date: Mon, 16 Dec 2024 17:26:43 -0800 Subject: [PATCH 02/13] chore: createPersistedStateFunction --- .../persistedState/createPersistedState.tsx | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/renderer/src/contexts/persistedState/createPersistedState.tsx diff --git a/src/renderer/src/contexts/persistedState/createPersistedState.tsx b/src/renderer/src/contexts/persistedState/createPersistedState.tsx new file mode 100644 index 0000000..583f1d7 --- /dev/null +++ b/src/renderer/src/contexts/persistedState/createPersistedState.tsx @@ -0,0 +1,128 @@ +import { createContext, useContext, type ReactNode } from 'react' +import { + createStore as createZustandStore, + useStore, + type StateCreator, + type StoreApi, +} from 'zustand' +import { persist } from 'zustand/middleware' + +type PersistedStoreKey = 'ActiveProjectId' + +/** + * Follows the pattern of injecting persisted state with a context. See + * https://tkdodo.eu/blog/zustand-and-react-context. Allows for easier testing + */ +export function createPersistedStoreWithProvider({ + slice, + actions, + persistedStoreKey, +}: { + slice: T + actions: StoreActions + persistedStoreKey: PersistedStoreKey +}) { + const Context = createContext> | null>(null) + + const Provider = ({ + children, + store, + }: { + children: ReactNode + store: ReturnType> + }) => { + return {children} + } + + function useCurrentContext() { + const context = useContext(Context) + if (!context) { + throw new Error(`${persistedStoreKey} context not properly initialized`) + } + return context + } + + // Hook to select store state + function useCurrentStore(selector: (state: T) => Selected) { + const context = useCurrentContext() + return useStore(context.store as StoreApi, selector) + } + + function useActions() { + const context = useCurrentContext() + return context.actions + } + + return { + Provider, + createStore: ({ isPersisted }: { isPersisted: boolean }) => { + return isPersisted + ? createStore({ isPersisted: true, persistedStoreKey, actions, slice }) + : createStore({ actions, slice, isPersisted: false }) + }, + useCurrentStore, + useActions, + } +} + +function createPersistedStore( + ...args: Parameters> +) { + const store = createZustandStore()(createPersistMiddleware(...args)) + store.setState((state) => ({ + ...state, + ...args[0], + })) + + return store +} + +function createPersistMiddleware( + slice: StateCreator, + persistedStoreKey: PersistedStoreKey, +) { + return persist(slice, { + name: persistedStoreKey, + }) +} + +type ActionCreator = ( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + newState: any, +) => (set: StoreApi['setState'], get: StoreApi['getState']) => void + +type StoreActions = { [key: string]: ActionCreator } + +type createStoreProps = { + slice: T + actions: StoreActions +} & ( + | { isPersisted: false } + | { isPersisted: true; persistedStoreKey: PersistedStoreKey } +) + +export function createStore(props: createStoreProps) { + let store: StoreApi + + if (!props.isPersisted) { + store = createZustandStore()(() => ({ ...props.slice })) + } else { + store = createPersistedStore( + () => ({ ...props.slice }), + props.persistedStoreKey, + ) + } + + const actions = Object.fromEntries( + Object.entries(props.actions).map(([key, action]) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const wrappedAction = (newState: any) => { + return action(newState)(store.setState, store.getState) // Pass `setState` and `getState` + } + + return [key, wrappedAction] + }), + ) as StoreActions + + return { store, actions } +} From 82dbbfc9e32078f9e6819668a2b60afe22de9b78 Mon Sep 17 00:00:00 2001 From: ErikSin <67773827+ErikSin@users.noreply.github.com> Date: Mon, 16 Dec 2024 17:27:06 -0800 Subject: [PATCH 03/13] chore: persisted active project Id --- src/renderer/src/App.tsx | 41 +++++++++++++++++++ .../persistedState/PersistedProjectId.tsx | 21 ++++++++++ src/renderer/src/index.tsx | 13 +----- src/renderer/src/routes/index.tsx | 6 +++ 4 files changed, 70 insertions(+), 11 deletions(-) create mode 100644 src/renderer/src/App.tsx create mode 100644 src/renderer/src/contexts/persistedState/PersistedProjectId.tsx diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx new file mode 100644 index 0000000..40e224d --- /dev/null +++ b/src/renderer/src/App.tsx @@ -0,0 +1,41 @@ +import { CssBaseline, ThemeProvider } from '@mui/material' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { RouterProvider, createRouter } from '@tanstack/react-router' + +import { theme } from './Theme' +import { ApiProvider } from './contexts/ApiContext' +import { IntlProvider } from './contexts/IntlContext' +import { + PersistedActiveProjectIdProvider, + createActiveProjectIdStore, +} from './contexts/persistedState/PersistedProjectId' +import { routeTree } from './routeTree.gen' + +const queryClient = new QueryClient() + +const router = createRouter({ routeTree }) + +declare module '@tanstack/react-router' { + interface Register { + router: typeof router + } +} + +const PersistedProjectIdStore = createActiveProjectIdStore({ + isPersisted: true, +}) + +export const App = () => ( + + + + + + + + + + + + +) diff --git a/src/renderer/src/contexts/persistedState/PersistedProjectId.tsx b/src/renderer/src/contexts/persistedState/PersistedProjectId.tsx new file mode 100644 index 0000000..934181e --- /dev/null +++ b/src/renderer/src/contexts/persistedState/PersistedProjectId.tsx @@ -0,0 +1,21 @@ +import { createPersistedStoreWithProvider } from './createPersistedState' + +type PersistedActiveProjectId = { projectId: string } + +const { Provider, createStore, useCurrentStore, useActions } = + createPersistedStoreWithProvider({ + slice: { projectId: 'newId' }, + actions: { + setProjectId: (newProjectId: string) => (set) => { + set({ projectId: newProjectId }) + }, + }, + persistedStoreKey: 'ActiveProjectId', + }) + +export { + Provider as PersistedActiveProjectIdProvider, + createStore as createActiveProjectIdStore, + useCurrentStore as usePersistedActiveProjectIdStore, + useActions as usePersistedActiveProjectIdActions, +} diff --git a/src/renderer/src/index.tsx b/src/renderer/src/index.tsx index 8cbe64a..63a2525 100644 --- a/src/renderer/src/index.tsx +++ b/src/renderer/src/index.tsx @@ -1,18 +1,9 @@ -import { RouterProvider, createRouter } from '@tanstack/react-router' import { createRoot } from 'react-dom/client' -import { routeTree } from './routeTree.gen' - import './index.css' -const router = createRouter({ routeTree }) - -declare module '@tanstack/react-router' { - interface Register { - router: typeof router - } -} +import { App } from './App' const root = createRoot(document.getElementById('app') as HTMLElement) -root.render() +root.render() diff --git a/src/renderer/src/routes/index.tsx b/src/renderer/src/routes/index.tsx index e6e06fe..744a649 100644 --- a/src/renderer/src/routes/index.tsx +++ b/src/renderer/src/routes/index.tsx @@ -2,6 +2,8 @@ import { useLayoutEffect } from 'react' import { useOwnDeviceInfo } from '@comapeo/core-react' import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { usePersistedActiveProjectIdStore } from '../contexts/persistedState/PersistedProjectId' + export const Route = createFileRoute('/')({ component: RouteComponent, }) @@ -13,10 +15,14 @@ function RouteComponent() { const navigate = useNavigate() const { data } = useOwnDeviceInfo() const hasCreatedDeviceName = data?.name !== undefined + const projectId = usePersistedActiveProjectIdStore((store) => store.projectId) useLayoutEffect(() => { if (!hasCreatedDeviceName) { navigate({ to: '/Onboarding' }) + } + if (!projectId) { + navigate({ to: '/Onboarding/CreateJoinProjectScreen' }) } else { navigate({ to: '/tab1' }) } From 448518efbbb395214e911aab5e47f82b6d73d133 Mon Sep 17 00:00:00 2001 From: ErikSin <67773827+ErikSin@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:01:09 -0800 Subject: [PATCH 04/13] chore: utility function to createStoreHooks --- .../src/contexts/createStoreHooks.tsx | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/renderer/src/contexts/createStoreHooks.tsx diff --git a/src/renderer/src/contexts/createStoreHooks.tsx b/src/renderer/src/contexts/createStoreHooks.tsx new file mode 100644 index 0000000..86ab785 --- /dev/null +++ b/src/renderer/src/contexts/createStoreHooks.tsx @@ -0,0 +1,31 @@ +import { useContext } from 'react' +import { useStore, type StoreApi } from 'zustand' + +export function createHooks( + context: React.Context<{ + store: StoreApi + actions: TStoreActions + } | null>, +) { + function useContextValue() { + const value = useContext(context) + if (!value) { + throw new Error('Must set up the provider first') + } + return value + } + + function useStoreState(): TStoreState + function useStoreState(selector: (state: TStoreState) => S): S + function useStoreState(selector?: (state: TStoreState) => S) { + const { store } = useContextValue() + return useStore(store, selector!) + } + + function useStoreActions() { + const { actions } = useContextValue() + return actions + } + + return { useStoreState, useStoreActions } +} From 9e6eb23fb632b0e29a3817e235b43b5c8c7fcb8d Mon Sep 17 00:00:00 2001 From: ErikSin <67773827+ErikSin@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:01:31 -0800 Subject: [PATCH 05/13] chore: create active project Id provider --- .../src/contexts/ActiveProjectIdProvider.tsx | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/renderer/src/contexts/ActiveProjectIdProvider.tsx diff --git a/src/renderer/src/contexts/ActiveProjectIdProvider.tsx b/src/renderer/src/contexts/ActiveProjectIdProvider.tsx new file mode 100644 index 0000000..75e4990 --- /dev/null +++ b/src/renderer/src/contexts/ActiveProjectIdProvider.tsx @@ -0,0 +1,63 @@ +import { createContext, type ReactNode } from 'react' +import { createStore, type StoreApi } from 'zustand' +import { persist as zustandPersist } from 'zustand/middleware' + +import { createHooks } from './createStoreHooks' + +const PERSISTED_ACTIVE_PROJECT_ID_KEY = 'ActiveProjectId' + +type ActiveProjectId = { activeProjectId: string | undefined } + +const initialActiveProjectId: ActiveProjectId = { + activeProjectId: undefined, +} + +type ActiveProjectIdStore = ReturnType + +type ActiveProjectIdProviderProps = { + children: ReactNode + store: ActiveProjectIdStore +} + +const ActiveProjectIdContext = createContext(null) + +export const ActiveProjectIdProvider = ({ + children, + store, +}: ActiveProjectIdProviderProps) => { + return ( + + {children} + + ) +} + +const { useStoreActions, useStoreState } = createHooks(ActiveProjectIdContext) + +export { + useStoreActions as useActiveProjectIdStoreActions, + useStoreState as useActiveProjectIdStoreState, +} + +export function CreateActiveProjectIdStore({ persist }: { persist: boolean }) { + let store: StoreApi + + if (!persist) { + store = createStore(() => initialActiveProjectId) + } else { + store = createStore( + zustandPersist(() => initialActiveProjectId, { + name: PERSISTED_ACTIVE_PROJECT_ID_KEY, + }), + ) + + store.setState(initialActiveProjectId) + } + + const actions = { + setProjectId: (newProjectId: string) => + store.setState({ activeProjectId: newProjectId }), + } + + return { store, actions } +} From 51558d1bee1af01c9d143fe3871319e195f151f9 Mon Sep 17 00:00:00 2001 From: ErikSin <67773827+ErikSin@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:03:32 -0800 Subject: [PATCH 06/13] chore: update app with new provider --- src/renderer/src/App.tsx | 16 +-- .../persistedState/PersistedProjectId.tsx | 21 --- .../persistedState/createPersistedState.tsx | 128 ------------------ 3 files changed, 8 insertions(+), 157 deletions(-) delete mode 100644 src/renderer/src/contexts/persistedState/PersistedProjectId.tsx delete mode 100644 src/renderer/src/contexts/persistedState/createPersistedState.tsx diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index 40e224d..e981e9c 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -3,12 +3,12 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { RouterProvider, createRouter } from '@tanstack/react-router' import { theme } from './Theme' +import { + ActiveProjectIdProvider, + CreateActiveProjectIdStore, +} from './contexts/ActiveProjectIdProvider' import { ApiProvider } from './contexts/ApiContext' import { IntlProvider } from './contexts/IntlContext' -import { - PersistedActiveProjectIdProvider, - createActiveProjectIdStore, -} from './contexts/persistedState/PersistedProjectId' import { routeTree } from './routeTree.gen' const queryClient = new QueryClient() @@ -21,8 +21,8 @@ declare module '@tanstack/react-router' { } } -const PersistedProjectIdStore = createActiveProjectIdStore({ - isPersisted: true, +const PersistedProjectIdStore = CreateActiveProjectIdStore({ + persist: true, }) export const App = () => ( @@ -30,11 +30,11 @@ export const App = () => ( - + - + diff --git a/src/renderer/src/contexts/persistedState/PersistedProjectId.tsx b/src/renderer/src/contexts/persistedState/PersistedProjectId.tsx deleted file mode 100644 index 934181e..0000000 --- a/src/renderer/src/contexts/persistedState/PersistedProjectId.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { createPersistedStoreWithProvider } from './createPersistedState' - -type PersistedActiveProjectId = { projectId: string } - -const { Provider, createStore, useCurrentStore, useActions } = - createPersistedStoreWithProvider({ - slice: { projectId: 'newId' }, - actions: { - setProjectId: (newProjectId: string) => (set) => { - set({ projectId: newProjectId }) - }, - }, - persistedStoreKey: 'ActiveProjectId', - }) - -export { - Provider as PersistedActiveProjectIdProvider, - createStore as createActiveProjectIdStore, - useCurrentStore as usePersistedActiveProjectIdStore, - useActions as usePersistedActiveProjectIdActions, -} diff --git a/src/renderer/src/contexts/persistedState/createPersistedState.tsx b/src/renderer/src/contexts/persistedState/createPersistedState.tsx deleted file mode 100644 index 583f1d7..0000000 --- a/src/renderer/src/contexts/persistedState/createPersistedState.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import { createContext, useContext, type ReactNode } from 'react' -import { - createStore as createZustandStore, - useStore, - type StateCreator, - type StoreApi, -} from 'zustand' -import { persist } from 'zustand/middleware' - -type PersistedStoreKey = 'ActiveProjectId' - -/** - * Follows the pattern of injecting persisted state with a context. See - * https://tkdodo.eu/blog/zustand-and-react-context. Allows for easier testing - */ -export function createPersistedStoreWithProvider({ - slice, - actions, - persistedStoreKey, -}: { - slice: T - actions: StoreActions - persistedStoreKey: PersistedStoreKey -}) { - const Context = createContext> | null>(null) - - const Provider = ({ - children, - store, - }: { - children: ReactNode - store: ReturnType> - }) => { - return {children} - } - - function useCurrentContext() { - const context = useContext(Context) - if (!context) { - throw new Error(`${persistedStoreKey} context not properly initialized`) - } - return context - } - - // Hook to select store state - function useCurrentStore(selector: (state: T) => Selected) { - const context = useCurrentContext() - return useStore(context.store as StoreApi, selector) - } - - function useActions() { - const context = useCurrentContext() - return context.actions - } - - return { - Provider, - createStore: ({ isPersisted }: { isPersisted: boolean }) => { - return isPersisted - ? createStore({ isPersisted: true, persistedStoreKey, actions, slice }) - : createStore({ actions, slice, isPersisted: false }) - }, - useCurrentStore, - useActions, - } -} - -function createPersistedStore( - ...args: Parameters> -) { - const store = createZustandStore()(createPersistMiddleware(...args)) - store.setState((state) => ({ - ...state, - ...args[0], - })) - - return store -} - -function createPersistMiddleware( - slice: StateCreator, - persistedStoreKey: PersistedStoreKey, -) { - return persist(slice, { - name: persistedStoreKey, - }) -} - -type ActionCreator = ( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - newState: any, -) => (set: StoreApi['setState'], get: StoreApi['getState']) => void - -type StoreActions = { [key: string]: ActionCreator } - -type createStoreProps = { - slice: T - actions: StoreActions -} & ( - | { isPersisted: false } - | { isPersisted: true; persistedStoreKey: PersistedStoreKey } -) - -export function createStore(props: createStoreProps) { - let store: StoreApi - - if (!props.isPersisted) { - store = createZustandStore()(() => ({ ...props.slice })) - } else { - store = createPersistedStore( - () => ({ ...props.slice }), - props.persistedStoreKey, - ) - } - - const actions = Object.fromEntries( - Object.entries(props.actions).map(([key, action]) => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const wrappedAction = (newState: any) => { - return action(newState)(store.setState, store.getState) // Pass `setState` and `getState` - } - - return [key, wrappedAction] - }), - ) as StoreActions - - return { store, actions } -} From 55b911395c1fdcd416086920cac79ca7078ee971 Mon Sep 17 00:00:00 2001 From: ErikSin <67773827+ErikSin@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:05:58 -0800 Subject: [PATCH 07/13] chore: update use of hook --- src/renderer/src/routes/index.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/renderer/src/routes/index.tsx b/src/renderer/src/routes/index.tsx index 744a649..2cddfc8 100644 --- a/src/renderer/src/routes/index.tsx +++ b/src/renderer/src/routes/index.tsx @@ -2,7 +2,7 @@ import { useLayoutEffect } from 'react' import { useOwnDeviceInfo } from '@comapeo/core-react' import { createFileRoute, useNavigate } from '@tanstack/react-router' -import { usePersistedActiveProjectIdStore } from '../contexts/persistedState/PersistedProjectId' +import { useActiveProjectIdStoreState } from '../contexts/ActiveProjectIdProvider' export const Route = createFileRoute('/')({ component: RouteComponent, @@ -15,13 +15,15 @@ function RouteComponent() { const navigate = useNavigate() const { data } = useOwnDeviceInfo() const hasCreatedDeviceName = data?.name !== undefined - const projectId = usePersistedActiveProjectIdStore((store) => store.projectId) + const activeProjectId = useActiveProjectIdStoreState( + (store) => store.activeProjectId, + ) useLayoutEffect(() => { if (!hasCreatedDeviceName) { navigate({ to: '/Onboarding' }) } - if (!projectId) { + if (!activeProjectId) { navigate({ to: '/Onboarding/CreateJoinProjectScreen' }) } else { navigate({ to: '/tab1' }) From 4e8e063e2681dd7fb53c60fbce55ab100e23a938 Mon Sep 17 00:00:00 2001 From: ErikSin <67773827+ErikSin@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:38:58 -0800 Subject: [PATCH 08/13] chore: remove unneccesary set state --- src/renderer/src/contexts/ActiveProjectIdProvider.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/renderer/src/contexts/ActiveProjectIdProvider.tsx b/src/renderer/src/contexts/ActiveProjectIdProvider.tsx index 75e4990..1789c5f 100644 --- a/src/renderer/src/contexts/ActiveProjectIdProvider.tsx +++ b/src/renderer/src/contexts/ActiveProjectIdProvider.tsx @@ -50,12 +50,10 @@ export function CreateActiveProjectIdStore({ persist }: { persist: boolean }) { name: PERSISTED_ACTIVE_PROJECT_ID_KEY, }), ) - - store.setState(initialActiveProjectId) } const actions = { - setProjectId: (newProjectId: string) => + setActiveProjectId: (newProjectId: string) => store.setState({ activeProjectId: newProjectId }), } From 723ef1ceb1e88a05e8b097dd80ce00f044bfa6f0 Mon Sep 17 00:00:00 2001 From: ErikSin <67773827+ErikSin@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:40:10 -0800 Subject: [PATCH 09/13] chore: create example use of zustand store with active project id --- .../src/routes/Onboarding/CreateProjectScreen.tsx | 5 ++++- src/renderer/src/routes/index.tsx | 11 ++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/renderer/src/routes/Onboarding/CreateProjectScreen.tsx b/src/renderer/src/routes/Onboarding/CreateProjectScreen.tsx index d5d8331..7d1e3d1 100644 --- a/src/renderer/src/routes/Onboarding/CreateProjectScreen.tsx +++ b/src/renderer/src/routes/Onboarding/CreateProjectScreen.tsx @@ -20,6 +20,7 @@ import { } from '../../components/Onboarding/onboardingLogic' import { Text } from '../../components/Text' import { PROJECT_NAME_MAX_LENGTH_GRAPHEMES } from '../../constants' +import { useActiveProjectIdStoreActions } from '../../contexts/ActiveProjectIdProvider' import { useCreateProject } from '../../hooks/mutations/projects' import ProjectImage from '../../images/add_square.png' @@ -110,6 +111,7 @@ function CreateProjectScreenComponent() { const [error, setError] = useState(false) const [errorMessage, setErrorMessage] = useState('') const setProjectNameMutation = useCreateProject() + const { setActiveProjectId } = useActiveProjectIdStoreActions() const [configFileName, setConfigFileName] = useState(null) @@ -134,7 +136,8 @@ function CreateProjectScreenComponent() { return } setProjectNameMutation.mutate(projectName, { - onSuccess: () => { + onSuccess: (projectId) => { + setActiveProjectId(projectId) navigate({ to: '/tab1' }) }, onError: (error) => { diff --git a/src/renderer/src/routes/index.tsx b/src/renderer/src/routes/index.tsx index 2cddfc8..b4f88b3 100644 --- a/src/renderer/src/routes/index.tsx +++ b/src/renderer/src/routes/index.tsx @@ -14,20 +14,25 @@ export const Route = createFileRoute('/')({ function RouteComponent() { const navigate = useNavigate() const { data } = useOwnDeviceInfo() - const hasCreatedDeviceName = data?.name !== undefined + const hasCreatedDeviceName = data.name !== undefined const activeProjectId = useActiveProjectIdStoreState( (store) => store.activeProjectId, ) + console.log({ activeProjectId }) + useLayoutEffect(() => { if (!hasCreatedDeviceName) { navigate({ to: '/Onboarding' }) + return } + if (!activeProjectId) { navigate({ to: '/Onboarding/CreateJoinProjectScreen' }) - } else { - navigate({ to: '/tab1' }) + return } + + navigate({ to: '/tab1' }) }) return null From f7a1cca95d5fabf5caca093766dab13d96d1eb58 Mon Sep 17 00:00:00 2001 From: ErikSin <67773827+ErikSin@users.noreply.github.com> Date: Wed, 18 Dec 2024 20:09:04 -0800 Subject: [PATCH 10/13] chore: remove duplicate providers --- src/renderer/src/routes/__root.tsx | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/src/renderer/src/routes/__root.tsx b/src/renderer/src/routes/__root.tsx index 7f8173e..c2132ca 100644 --- a/src/renderer/src/routes/__root.tsx +++ b/src/renderer/src/routes/__root.tsx @@ -1,28 +1,11 @@ import { Suspense } from 'react' -import { CssBaseline, ThemeProvider } from '@mui/material' import CircularProgress from '@mui/material/CircularProgress' -import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { Outlet, createRootRoute } from '@tanstack/react-router' -import { theme } from '../Theme' -import { ApiProvider } from '../contexts/ApiContext' -import { IntlProvider } from '../contexts/IntlContext' - -const queryClient = new QueryClient() - export const Route = createRootRoute({ component: () => ( - - - - - - }> - - - - - - + }> + + ), }) From 2a8ae4cfd6a50bc58fbfd0d59a88606d80b80d25 Mon Sep 17 00:00:00 2001 From: ErikSin <67773827+ErikSin@users.noreply.github.com> Date: Wed, 18 Dec 2024 20:13:29 -0800 Subject: [PATCH 11/13] chore: remove console log --- src/renderer/src/routes/index.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/renderer/src/routes/index.tsx b/src/renderer/src/routes/index.tsx index b4f88b3..7a2325d 100644 --- a/src/renderer/src/routes/index.tsx +++ b/src/renderer/src/routes/index.tsx @@ -19,8 +19,6 @@ function RouteComponent() { (store) => store.activeProjectId, ) - console.log({ activeProjectId }) - useLayoutEffect(() => { if (!hasCreatedDeviceName) { navigate({ to: '/Onboarding' }) From 5b69aa7d1806f2a3219de1fdff771afdc35ce24a Mon Sep 17 00:00:00 2001 From: ErikSin <67773827+ErikSin@users.noreply.github.com> Date: Wed, 18 Dec 2024 20:13:45 -0800 Subject: [PATCH 12/13] chore: change function casing --- src/renderer/src/App.tsx | 4 ++-- src/renderer/src/contexts/ActiveProjectIdProvider.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index e981e9c..eb67abb 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -5,7 +5,7 @@ import { RouterProvider, createRouter } from '@tanstack/react-router' import { theme } from './Theme' import { ActiveProjectIdProvider, - CreateActiveProjectIdStore, + createActiveProjectIdStore, } from './contexts/ActiveProjectIdProvider' import { ApiProvider } from './contexts/ApiContext' import { IntlProvider } from './contexts/IntlContext' @@ -21,7 +21,7 @@ declare module '@tanstack/react-router' { } } -const PersistedProjectIdStore = CreateActiveProjectIdStore({ +const PersistedProjectIdStore = createActiveProjectIdStore({ persist: true, }) diff --git a/src/renderer/src/contexts/ActiveProjectIdProvider.tsx b/src/renderer/src/contexts/ActiveProjectIdProvider.tsx index 1789c5f..2f20632 100644 --- a/src/renderer/src/contexts/ActiveProjectIdProvider.tsx +++ b/src/renderer/src/contexts/ActiveProjectIdProvider.tsx @@ -39,7 +39,7 @@ export { useStoreState as useActiveProjectIdStoreState, } -export function CreateActiveProjectIdStore({ persist }: { persist: boolean }) { +export function createActiveProjectIdStore({ persist }: { persist: boolean }) { let store: StoreApi if (!persist) { From 89de469b051646d4e732594492fe3f120e6c1114 Mon Sep 17 00:00:00 2001 From: ErikSin <67773827+ErikSin@users.noreply.github.com> Date: Wed, 18 Dec 2024 20:16:46 -0800 Subject: [PATCH 13/13] chore: update casing --- src/renderer/src/contexts/ActiveProjectIdProvider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/src/contexts/ActiveProjectIdProvider.tsx b/src/renderer/src/contexts/ActiveProjectIdProvider.tsx index 2f20632..112ad34 100644 --- a/src/renderer/src/contexts/ActiveProjectIdProvider.tsx +++ b/src/renderer/src/contexts/ActiveProjectIdProvider.tsx @@ -12,7 +12,7 @@ const initialActiveProjectId: ActiveProjectId = { activeProjectId: undefined, } -type ActiveProjectIdStore = ReturnType +type ActiveProjectIdStore = ReturnType type ActiveProjectIdProviderProps = { children: ReactNode