mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-21 20:16:26 +08:00
refactor: lazy load workspaces (#3091)
(cherry picked from commit 283f0cd263)
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
import { Button, displayFlex, styled } from '@affine/component';
|
||||
import { WorkspaceSubPath } from '@affine/env/workspace';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import Head from 'next/head';
|
||||
import Image from 'next/legacy/image';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
|
||||
import { useRouterHelper } from '../hooks/use-router-helper';
|
||||
|
||||
export const StyledContainer = styled('div')(() => {
|
||||
return {
|
||||
...displayFlex('center', 'center'),
|
||||
@@ -26,6 +29,7 @@ export const StyledContainer = styled('div')(() => {
|
||||
export const NotfoundPage = () => {
|
||||
const t = useAFFiNEI18N();
|
||||
const router = useRouter();
|
||||
const { jumpToSubPath } = useRouterHelper(router);
|
||||
return (
|
||||
<StyledContainer data-testid="notFound">
|
||||
<Image alt="404" src="/imgs/invite-error.svg" width={360} height={270} />
|
||||
@@ -34,7 +38,12 @@ export const NotfoundPage = () => {
|
||||
<Button
|
||||
shape="round"
|
||||
onClick={() => {
|
||||
router.push('/').catch(err => console.error(err));
|
||||
const id = localStorage.getItem('last_workspace_id');
|
||||
if (id) {
|
||||
jumpToSubPath(id, WorkspaceSubPath.ALL).catch(console.error);
|
||||
} else {
|
||||
router.push('/').catch(err => console.error(err));
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t['Back Home']()}
|
||||
|
||||
@@ -1,22 +1,33 @@
|
||||
import { WorkspaceFallback } from '@affine/component/workspace';
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { WorkspaceSubPath } from '@affine/env/workspace';
|
||||
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||
import { getWorkspace } from '@affine/workspace/utils';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import type { NextPage } from 'next';
|
||||
import { useRouter } from 'next/router';
|
||||
import { Suspense, useEffect } from 'react';
|
||||
|
||||
import { PageLoading } from '../components/pure/loading';
|
||||
import { RouteLogic, useRouterHelper } from '../hooks/use-router-helper';
|
||||
import { useAppHelper, useWorkspaces } from '../hooks/use-workspaces';
|
||||
import { AllWorkspaceContext } from '../layouts/workspace-layout';
|
||||
import { useWorkspace } from '../hooks/use-workspace';
|
||||
import { useAppHelper } from '../hooks/use-workspaces';
|
||||
import { AllWorkspaceModals } from '../providers/modal-provider';
|
||||
|
||||
const logger = new DebugLogger('index-page');
|
||||
const logger = new DebugLogger('index:router');
|
||||
|
||||
type AllWorkspaceLoaderProps = {
|
||||
id: string;
|
||||
};
|
||||
|
||||
const WorkspaceLoader = (props: AllWorkspaceLoaderProps): null => {
|
||||
useWorkspace(props.id);
|
||||
return null;
|
||||
};
|
||||
|
||||
const IndexPageInner = () => {
|
||||
const router = useRouter();
|
||||
const { jumpToPage, jumpToSubPath } = useRouterHelper(router);
|
||||
const workspaces = useWorkspaces();
|
||||
const meta = useAtomValue(rootWorkspacesMetadataAtom);
|
||||
const helper = useAppHelper();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -25,15 +36,14 @@ const IndexPageInner = () => {
|
||||
}
|
||||
const lastId = localStorage.getItem('last_workspace_id');
|
||||
const lastPageId = localStorage.getItem('last_page_id');
|
||||
const targetWorkspace =
|
||||
(lastId && workspaces.find(({ id }) => id === lastId)) ||
|
||||
workspaces.at(0);
|
||||
|
||||
if (targetWorkspace) {
|
||||
const nonTrashPages =
|
||||
targetWorkspace.blockSuiteWorkspace.meta.pageMetas.filter(
|
||||
({ trash }) => !trash
|
||||
);
|
||||
const target =
|
||||
(lastId && meta.find(({ id }) => id === lastId)) || meta.at(0);
|
||||
if (target) {
|
||||
const targetWorkspace = getWorkspace(target.id);
|
||||
const nonTrashPages = targetWorkspace.meta.pageMetas.filter(
|
||||
({ trash }) => !trash
|
||||
);
|
||||
const pageId =
|
||||
nonTrashPages.find(({ id }) => id === lastPageId)?.id ??
|
||||
nonTrashPages.at(0)?.id;
|
||||
@@ -56,38 +66,38 @@ const IndexPageInner = () => {
|
||||
console.error(err);
|
||||
});
|
||||
}, 1000);
|
||||
const dispose =
|
||||
targetWorkspace.blockSuiteWorkspace.slots.pageAdded.once(pageId => {
|
||||
clearTimeout(clearId);
|
||||
jumpToPage(targetWorkspace.id, pageId, RouteLogic.REPLACE).catch(
|
||||
err => {
|
||||
console.error(err);
|
||||
}
|
||||
);
|
||||
});
|
||||
const dispose = targetWorkspace.slots.pageAdded.once(pageId => {
|
||||
clearTimeout(clearId);
|
||||
jumpToPage(targetWorkspace.id, pageId, RouteLogic.REPLACE).catch(
|
||||
err => {
|
||||
console.error(err);
|
||||
}
|
||||
);
|
||||
});
|
||||
return () => {
|
||||
clearTimeout(clearId);
|
||||
dispose.dispose();
|
||||
};
|
||||
}
|
||||
} else {
|
||||
console.warn('No target workspace. This should not happen in production');
|
||||
console.warn('No workspace found');
|
||||
}
|
||||
return;
|
||||
}, [helper, jumpToPage, jumpToSubPath, router, workspaces]);
|
||||
}, [meta, helper, jumpToPage, jumpToSubPath, router]);
|
||||
|
||||
return (
|
||||
<Suspense fallback={<WorkspaceFallback />}>
|
||||
<AllWorkspaceContext>
|
||||
<AllWorkspaceModals />
|
||||
</AllWorkspaceContext>
|
||||
</Suspense>
|
||||
<>
|
||||
{meta.map(({ id }) => (
|
||||
<WorkspaceLoader key={id} id={id} />
|
||||
))}
|
||||
<AllWorkspaceModals />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const IndexPage: NextPage = () => {
|
||||
return (
|
||||
<Suspense fallback={<PageLoading />}>
|
||||
<Suspense fallback={<WorkspaceFallback />}>
|
||||
<IndexPageInner />
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
@@ -8,7 +8,6 @@ import { rootCurrentPageIdAtom } from '@affine/workspace/atom';
|
||||
import type { EditorContainer } from '@blocksuite/editor';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
import { useBlockSuiteWorkspacePage } from '@toeverything/hooks/use-block-suite-workspace-page';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import { useRouter } from 'next/router';
|
||||
import type React from 'react';
|
||||
@@ -16,7 +15,6 @@ import { useCallback } from 'react';
|
||||
|
||||
import { getUIAdapter } from '../../../adapters/workspace';
|
||||
import { pageSettingFamily } from '../../../atoms';
|
||||
import { rootCurrentWorkspaceAtom } from '../../../atoms/root';
|
||||
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
|
||||
import { useRouterHelper } from '../../../hooks/use-router-helper';
|
||||
import { WorkspaceLayout } from '../../../layouts/workspace-layout';
|
||||
@@ -65,13 +63,13 @@ const WorkspaceDetail: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<Header
|
||||
currentWorkspace={currentWorkspace}
|
||||
currentWorkspaceId={currentWorkspace.id}
|
||||
currentEntry={{
|
||||
pageId: currentPageId,
|
||||
}}
|
||||
/>
|
||||
<PageDetail
|
||||
currentWorkspace={currentWorkspace}
|
||||
currentWorkspaceId={currentWorkspace.id}
|
||||
currentPageId={currentPageId}
|
||||
onLoadEditor={onLoad}
|
||||
/>
|
||||
@@ -81,12 +79,11 @@ const WorkspaceDetail: React.FC = () => {
|
||||
|
||||
const WorkspaceDetailPage: NextPageWithLayout = () => {
|
||||
const router = useRouter();
|
||||
const currentWorkspace = useAtomValue(rootCurrentWorkspaceAtom);
|
||||
const [currentWorkspace] = useCurrentWorkspace();
|
||||
const currentPageId = useAtomValue(rootCurrentPageIdAtom);
|
||||
const page = useBlockSuiteWorkspacePage(
|
||||
currentWorkspace.blockSuiteWorkspace,
|
||||
currentPageId
|
||||
);
|
||||
const page = currentPageId
|
||||
? currentWorkspace.blockSuiteWorkspace.getPage(currentPageId)
|
||||
: null;
|
||||
if (!router.isReady) {
|
||||
return <PageDetailSkeleton key="router-not-ready" />;
|
||||
} else if (!currentPageId || !page) {
|
||||
|
||||
@@ -45,7 +45,7 @@ const AllPage: NextPageWithLayout = () => {
|
||||
<title>{t['All pages']()} - AFFiNE</title>
|
||||
</Head>
|
||||
<Header
|
||||
currentWorkspace={currentWorkspace}
|
||||
currentWorkspaceId={currentWorkspace.id}
|
||||
currentEntry={{
|
||||
subPath: WorkspaceSubPath.ALL,
|
||||
}}
|
||||
|
||||
@@ -40,7 +40,7 @@ const SharedPages: NextPageWithLayout = () => {
|
||||
<title>{t['Shared Pages']()} - AFFiNE</title>
|
||||
</Head>
|
||||
<Header
|
||||
currentWorkspace={currentWorkspace}
|
||||
currentWorkspaceId={currentWorkspace.id}
|
||||
currentEntry={{
|
||||
subPath: WorkspaceSubPath.SHARED,
|
||||
}}
|
||||
|
||||
@@ -44,7 +44,7 @@ const TrashPage: NextPageWithLayout = () => {
|
||||
<title>{t['Trash']()} - AFFiNE</title>
|
||||
</Head>
|
||||
<Header
|
||||
currentWorkspace={currentWorkspace}
|
||||
currentWorkspaceId={currentWorkspace.id}
|
||||
currentEntry={{
|
||||
subPath: WorkspaceSubPath.TRASH,
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user