fix: add router defend

This commit is contained in:
QiShaoXuan
2022-12-22 18:35:51 +08:00
parent cc910dd9e9
commit a64f77c9d2
18 changed files with 284 additions and 120 deletions
+23 -6
View File
@@ -8,12 +8,15 @@ import '@fontsource/space-mono';
import '@fontsource/poppins';
import '../utils/print-build-info';
import ProviderComposer from '@/components/provider-composer';
import type { ReactElement, ReactNode } from 'react';
import type { PropsWithChildren, ReactElement, ReactNode } from 'react';
import type { NextPage } from 'next';
import { AppStateProvider } from '@/providers/app-state-provider/provider';
import ConfirmProvider from '@/providers/confirm-provider';
import { ModalProvider } from '@/providers/global-modal-provider';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import { useAppState } from '@/providers/app-state-provider';
import { PageLoading } from '@/components/loading';
const ThemeProvider = dynamic(() => import('@/providers/themeProvider'), {
ssr: false,
});
@@ -26,7 +29,7 @@ type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout;
};
function MyApp({ Component, pageProps }: AppPropsWithLayout) {
const App = ({ Component, pageProps }: AppPropsWithLayout) => {
const getLayout = Component.getLayout || (page => page);
return (
@@ -40,10 +43,24 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
<ConfirmProvider key="ConfirmProvider" />,
]}
>
{getLayout(<Component {...pageProps} />)}
<AppDefender>{getLayout(<Component {...pageProps} />)}</AppDefender>
</ProviderComposer>
</>
);
}
};
export default MyApp;
const AppDefender = ({ children }: PropsWithChildren) => {
const router = useRouter();
const { synced } = useAppState();
useEffect(() => {
if (router.pathname === '/') {
router.replace('/workspace');
}
}, [router]);
return <div>{synced ? children : <PageLoading />}</div>;
};
export default App;
@@ -1,16 +1,19 @@
import { useRef, useEffect, ReactElement } from 'react';
import {
useRef,
useEffect,
useState,
ReactElement,
PropsWithChildren,
} from 'react';
import { styled } from '@/styles';
import { EditorHeader } from '@/components/header';
import EdgelessToolbar from '@/components/edgeless-toolbar';
import MobileModal from '@/components/mobile-modal';
import {
useLoadWorkspace,
useLoadPage,
} from '@/providers/app-state-provider/hooks';
import { useAppState } from '@/providers/app-state-provider/context';
import exampleMarkdown from '@/static/example-markdown';
import type { NextPageWithLayout } from '../..//_app';
import WorkspaceLayout from '@/components/workspace-layout';
import { useRouter } from 'next/router';
const StyledEditorContainer = styled('div')(({ theme }) => {
return {
@@ -20,9 +23,8 @@ const StyledEditorContainer = styled('div')(({ theme }) => {
const Page: NextPageWithLayout = () => {
const editorContainer = useRef<HTMLDivElement>(null);
const workspace = useLoadWorkspace();
const page = useLoadPage();
const { createEditor, setEditor } = useAppState();
const { createEditor, setEditor, currentPage, currentWorkspace } =
useAppState();
useEffect(() => {
const ret = () => {
@@ -32,29 +34,29 @@ const Page: NextPageWithLayout = () => {
}
};
if (!workspace || !page) {
return ret;
}
const editor = createEditor?.current?.(page);
const editor = createEditor?.current?.(currentPage!);
if (editor) {
editorContainer.current?.appendChild(editor);
setEditor?.current?.(editor);
if (page.isEmpty) {
if (currentPage!.isEmpty) {
const title = 'Welcome to the AFFiNE Alpha';
const pageId = page.addBlock({
const pageId = currentPage!.addBlock({
flavour: 'affine:page',
title,
});
const groupId = page.addBlock({ flavour: 'affine:group' }, pageId);
const groupId = currentPage!.addBlock(
{ flavour: 'affine:group' },
pageId
);
editor.clipboard.importMarkdown(exampleMarkdown, `${groupId}`);
workspace.setPageMeta(page.id, { title });
page.resetHistory();
currentWorkspace!.setPageMeta(currentPage!.id, { title });
currentPage!.resetHistory();
}
}
return ret;
}, [workspace, page, createEditor, setEditor]);
}, [currentWorkspace, currentPage, createEditor, setEditor]);
return (
<>
@@ -66,8 +68,34 @@ const Page: NextPageWithLayout = () => {
);
};
const PageDefender = ({ children }: PropsWithChildren) => {
const router = useRouter();
const [pageLoaded, setPageLoaded] = useState(false);
const { currentWorkspace, createPage, loadPage } = useAppState();
useEffect(() => {
const initPage = async () => {
const pageId = router.query.pageId as string;
const isPageExist = !!currentWorkspace!.meta.pageMetas.find(
p => p.id === pageId
);
if (!isPageExist) {
await createPage(pageId);
}
await loadPage(pageId);
setPageLoaded(true);
};
initPage();
}, [createPage, currentWorkspace, loadPage, router.query.pageId]);
return <>{pageLoaded ? children : null}</>;
};
Page.getLayout = function getLayout(page: ReactElement) {
return <WorkspaceLayout>{page}</WorkspaceLayout>;
return (
<WorkspaceLayout>
<PageDefender>{page}</PageDefender>
</WorkspaceLayout>
);
};
export default Page;
@@ -1,17 +1,14 @@
import { useLoadWorkspace } from '@/providers/app-state-provider/hooks';
import { PageList } from '@/components/page-list';
import { AllPagesIcon } from '@blocksuite/icons';
import usePageMetaList from '@/hooks/use-page-meta-list';
import { PageListHeader } from '@/components/header';
import { NextPageWithLayout } from '@/pages/_app';
import { ReactElement } from 'react';
import WorkspaceLayout from '@/components/workspace-layout';
const All: NextPageWithLayout = () => {
const workspace = useLoadWorkspace();
const All = () => {
const pageMetaList = usePageMetaList();
return workspace ? (
return (
<>
<PageListHeader icon={<AllPagesIcon />}>All Page</PageListHeader>
<PageList
@@ -19,7 +16,7 @@ const All: NextPageWithLayout = () => {
showFavoriteTag={true}
/>
</>
) : null;
);
};
All.getLayout = function getLayout(page: ReactElement) {
@@ -1,21 +1,18 @@
import { useLoadWorkspace } from '@/providers/app-state-provider/hooks';
import { PageListHeader } from '@/components/header';
import { PageList } from '@/components/page-list';
import { FavouritesIcon } from '@blocksuite/icons';
import usePageMetaList from '@/hooks/use-page-meta-list';
import { NextPageWithLayout } from '@/pages/_app';
import { ReactElement } from 'react';
import WorkspaceLayout from '@/components/workspace-layout';
export const Favorite: NextPageWithLayout = () => {
const workspace = useLoadWorkspace();
export const Favorite = () => {
const pageMetaList = usePageMetaList();
return workspace ? (
return (
<>
<PageListHeader icon={<FavouritesIcon />}>Favourites</PageListHeader>
<PageList pageList={pageMetaList.filter(p => p.favorite && !p.trash)} />
</>
) : null;
);
};
Favorite.getLayout = function getLayout(page: ReactElement) {
return <WorkspaceLayout>{page}</WorkspaceLayout>;
@@ -1,13 +1,31 @@
import {
useLoadWorkspace,
useLoadPage,
} from '@/providers/app-state-provider/hooks';
import React, { ReactElement, useEffect } from 'react';
import { useRouter } from 'next/router';
import { useAppState } from '@/providers/app-state-provider/context';
import WorkspaceLayout from '@/components/workspace-layout';
const Page = () => {
useLoadWorkspace();
useLoadPage();
const WorkspaceIndex = () => {
const router = useRouter();
const { createPage, currentWorkspaceId, currentWorkspace } = useAppState();
useEffect(() => {
const initPage = async () => {
const savedPageId = currentWorkspace!.meta.pageMetas[0]?.id;
if (savedPageId) {
router.replace(`/workspace/${currentWorkspaceId}/${savedPageId}`);
return;
}
const pageId = await createPage();
router.replace(`/workspace/${currentWorkspaceId}/${pageId}`);
};
initPage();
}, [currentWorkspace, currentWorkspaceId, createPage, router]);
return <></>;
};
export default Page;
WorkspaceIndex.getLayout = function getLayout(page: ReactElement) {
return <WorkspaceLayout>{page}</WorkspaceLayout>;
};
export default WorkspaceIndex;
@@ -1,21 +1,18 @@
import { useLoadWorkspace } from '@/providers/app-state-provider/hooks';
import { PageListHeader } from '@/components/header';
import { PageList } from '@/components/page-list';
import { TrashIcon } from '@blocksuite/icons';
import usePageMetaList from '@/hooks/use-page-meta-list';
import { NextPageWithLayout } from '@/pages/_app';
import { ReactElement } from 'react';
import WorkspaceLayout from '@/components/workspace-layout';
export const Trash: NextPageWithLayout = () => {
const workspace = useLoadWorkspace();
export const Trash = () => {
const pageMetaList = usePageMetaList();
return workspace ? (
return (
<>
<PageListHeader icon={<TrashIcon />}>Trash</PageListHeader>
<PageList pageList={pageMetaList.filter(p => p.trash)} isTrash={true} />
</>
) : null;
);
};
Trash.getLayout = function getLayout(page: ReactElement) {
+19 -3
View File
@@ -1,5 +1,21 @@
const Page = () => {
return <div>Hello, there is [workspace]/index.</div>;
import React, { ReactElement, useEffect } from 'react';
import WorkspaceLayout from '@/components/workspace-layout';
import { useAppState } from '@/providers/app-state-provider';
import { useRouter } from 'next/router';
export const WorkspaceIndex = () => {
const router = useRouter();
const { currentWorkspaceId } = useAppState();
useEffect(() => {
if (currentWorkspaceId) {
router.replace(`/workspace/${currentWorkspaceId}`);
}
}, [currentWorkspaceId, router]);
return <></>;
};
export default Page;
WorkspaceIndex.getLayout = function getLayout(page: ReactElement) {
return <WorkspaceLayout>{page}</WorkspaceLayout>;
};
export default WorkspaceIndex;