From c58dd6f403257054e8c18ab10df58d21fa6ef4fb Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Fri, 23 Dec 2022 19:04:42 +0800 Subject: [PATCH] feat: modify router logic, can not create workspace by router query --- .../src/components/workspace-layout/index.tsx | 9 ++-- .../app/src/hooks/use-ensure-workspace.ts | 54 +++++++++++++++++++ .../pages/workspace/[workspaceId]/index.tsx | 18 ++++--- packages/app/src/pages/workspace/index.tsx | 12 +++-- .../providers/app-state-provider/provider.tsx | 3 +- 5 files changed, 78 insertions(+), 18 deletions(-) create mode 100644 packages/app/src/hooks/use-ensure-workspace.ts diff --git a/packages/app/src/components/workspace-layout/index.tsx b/packages/app/src/components/workspace-layout/index.tsx index 46aa3701e7..3da85a5ad4 100644 --- a/packages/app/src/components/workspace-layout/index.tsx +++ b/packages/app/src/components/workspace-layout/index.tsx @@ -3,14 +3,11 @@ import { WorkSpaceSliderBar } from '@/components/workspace-slider-bar'; import { useRouter } from 'next/router'; import { StyledPage, StyledWrapper } from './styles'; import { PropsWithChildren } from 'react'; -import { useAppState } from '@/providers/app-state-provider'; -import { useInitWorkspace } from '@/hooks/use-init-workspace'; +import useEnsureWorkspace from '@/hooks/use-ensure-workspace'; export const WorkspaceDefender = ({ children }: PropsWithChildren) => { - const { synced } = useAppState(); - const { loading } = useInitWorkspace(!synced); - - return <>{!loading ? children : null}; + const { workspaceLoaded } = useEnsureWorkspace(); + return <>{workspaceLoaded ? children : null}; }; export const WorkspaceLayout = ({ children }: PropsWithChildren) => { diff --git a/packages/app/src/hooks/use-ensure-workspace.ts b/packages/app/src/hooks/use-ensure-workspace.ts new file mode 100644 index 0000000000..60009d8298 --- /dev/null +++ b/packages/app/src/hooks/use-ensure-workspace.ts @@ -0,0 +1,54 @@ +import { useState, useEffect } from 'react'; +import { useAppState } from '@/providers/app-state-provider'; +import { useRouter } from 'next/router'; + +// It is a fully effective hook +// Cause it not just ensure workspace loaded, but also have router change. +export const useEnsureWorkspace = () => { + const [workspaceLoaded, setWorkspaceLoaded] = useState(false); + const { workspacesMeta, loadWorkspace, synced, user } = useAppState(); + const router = useRouter(); + const defaultOutLineWorkspaceId = '112233'; + + useEffect(() => { + if (!synced) { + setWorkspaceLoaded(false); + return; + } + // If router.query.workspaceId is not in workspace list, jump to 404 page + // If workspacesMeta is empty, we need to create a default workspace but not jump to 404 + if ( + workspacesMeta.length && + router.query.workspaceId && + workspacesMeta.findIndex( + meta => meta.id.toString() === router.query.workspaceId + ) === -1 + ) { + router.push('/404'); + return; + } + // If user is not login and input a custom workspaceId, jump to 404 page + if ( + !user && + router.query.workspaceId && + router.query.workspaceId !== defaultOutLineWorkspaceId + ) { + router.push('/404'); + return; + } + + const workspaceId = user + ? (router.query.workspaceId as string) || workspacesMeta?.[0]?.id + : defaultOutLineWorkspaceId; + + loadWorkspace(workspaceId).finally(() => { + setWorkspaceLoaded(true); + }); + }, [loadWorkspace, router, synced, user, workspacesMeta]); + + return { + workspaceLoaded, + }; +}; + +export default useEnsureWorkspace; diff --git a/packages/app/src/pages/workspace/[workspaceId]/index.tsx b/packages/app/src/pages/workspace/[workspaceId]/index.tsx index 2b3bc8f8bd..c7b158b2f9 100644 --- a/packages/app/src/pages/workspace/[workspaceId]/index.tsx +++ b/packages/app/src/pages/workspace/[workspaceId]/index.tsx @@ -1,19 +1,19 @@ import { useEffect } from 'react'; import { useRouter } from 'next/router'; import { useAppState } from '@/providers/app-state-provider/context'; -import { useInitWorkspace } from '@/hooks/use-init-workspace'; +import useEnsureWorkspace from '@/hooks/use-ensure-workspace'; const WorkspaceIndex = () => { const router = useRouter(); - const { createPage, currentWorkspaceId } = useAppState(); - const { workspace } = useInitWorkspace(); + const { createPage, currentWorkspaceId, currentWorkspace } = useAppState(); + const { workspaceLoaded } = useEnsureWorkspace(); useEffect(() => { const initPage = async () => { - if (!workspace) { + if (!workspaceLoaded) { return; } - const savedPageId = workspace.meta.pageMetas[0]?.id; + const savedPageId = currentWorkspace?.meta.pageMetas[0]?.id; if (savedPageId) { router.replace(`/workspace/${currentWorkspaceId}/${savedPageId}`); return; @@ -23,7 +23,13 @@ const WorkspaceIndex = () => { router.replace(`/workspace/${currentWorkspaceId}/${pageId}`); }; initPage(); - }, [workspace, currentWorkspaceId, createPage, router]); + }, [ + currentWorkspace, + currentWorkspaceId, + createPage, + router, + workspaceLoaded, + ]); return <>; }; diff --git a/packages/app/src/pages/workspace/index.tsx b/packages/app/src/pages/workspace/index.tsx index 244c91763a..d81e348517 100644 --- a/packages/app/src/pages/workspace/index.tsx +++ b/packages/app/src/pages/workspace/index.tsx @@ -1,16 +1,18 @@ import { useEffect } from 'react'; import { useRouter } from 'next/router'; -import { useInitWorkspace } from '@/hooks/use-init-workspace'; +import { useAppState } from '@/providers/app-state-provider'; +import useEnsureWorkspace from '@/hooks/use-ensure-workspace'; export const WorkspaceIndex = () => { const router = useRouter(); - const { workspaceId, workspace } = useInitWorkspace(); + const { currentWorkspaceId } = useAppState(); + const { workspaceLoaded } = useEnsureWorkspace(); useEffect(() => { - if (workspace) { - router.push(`/workspace/${workspaceId}`); + if (workspaceLoaded) { + router.push(`/workspace/${currentWorkspaceId}`); } - }, [router, workspace, workspaceId]); + }, [currentWorkspaceId, router, workspaceLoaded]); return <>; }; diff --git a/packages/app/src/providers/app-state-provider/provider.tsx b/packages/app/src/providers/app-state-provider/provider.tsx index ee6cbc97f8..6a344fa61f 100644 --- a/packages/app/src/providers/app-state-provider/provider.tsx +++ b/packages/app/src/providers/app-state-provider/provider.tsx @@ -194,6 +194,7 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => { return; } const callback = async (user: AccessTokenMessage | null) => { + const isLogin = token.isLogin; const workspacesMeta = user ? await getWorkspaces().catch(() => { return []; @@ -204,7 +205,7 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => { ...state, user: user, workspacesMeta, - synced: true, + synced: isLogin ? !!user : true, })); }; token.onChange(callback);