refactor: support suspense mode in workspaces (#1304)
This commit is contained in:
@@ -1,57 +1,100 @@
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { setUpLanguage, useTranslation } from '@affine/i18n';
|
||||
import { assertExists, nanoid } from '@blocksuite/store';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import { NoSsr } from '@mui/material';
|
||||
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
|
||||
import { atomWithStorage } from 'jotai/utils';
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import React, { Suspense, useCallback, useEffect } from 'react';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
|
||||
import {
|
||||
currentWorkspaceIdAtom,
|
||||
jotaiWorkspacesAtom,
|
||||
openQuickSearchModalAtom,
|
||||
openWorkspacesModalAtom,
|
||||
workspaceLockAtom,
|
||||
} from '../atoms';
|
||||
import { HelpIsland } from '../components/pure/help-island';
|
||||
import { PageLoading } from '../components/pure/loading';
|
||||
import QuickSearchModal from '../components/pure/quick-search-modal';
|
||||
import WorkSpaceSliderBar from '../components/pure/workspace-slider-bar';
|
||||
import { useCurrentPageId } from '../hooks/current/use-current-page-id';
|
||||
import { useCurrentWorkspace } from '../hooks/current/use-current-workspace';
|
||||
import { useBlockSuiteWorkspaceHelper } from '../hooks/use-blocksuite-workspace-helper';
|
||||
import { useCreateFirstWorkspace } from '../hooks/use-create-first-workspace';
|
||||
import { useRouterTitle } from '../hooks/use-router-title';
|
||||
import {
|
||||
refreshDataCenter,
|
||||
useSyncWorkspaces,
|
||||
useWorkspaces,
|
||||
} from '../hooks/use-workspaces';
|
||||
import { useWorkspaces } from '../hooks/use-workspaces';
|
||||
import { WorkspacePlugins } from '../plugins';
|
||||
import { ModalProvider } from '../providers/ModalProvider';
|
||||
import { pathGenerator, publicPathGenerator } from '../shared';
|
||||
import { StyledPage, StyledToolWrapper, StyledWrapper } from './styles';
|
||||
|
||||
const sideBarOpenAtom = atomWithStorage('sideBarOpen', true);
|
||||
|
||||
refreshDataCenter();
|
||||
const logger = new DebugLogger('workspace-layout');
|
||||
export const WorkspaceLayout: React.FC<React.PropsWithChildren> =
|
||||
function WorkspacesSuspense({ children }) {
|
||||
const { i18n } = useTranslation();
|
||||
useEffect(() => {
|
||||
document.documentElement.lang = i18n.language;
|
||||
// todo(himself65): this is a hack, we should use a better way to set the language
|
||||
setUpLanguage(i18n);
|
||||
}, [i18n]);
|
||||
useCreateFirstWorkspace();
|
||||
const set = useSetAtom(jotaiWorkspacesAtom);
|
||||
useEffect(() => {
|
||||
logger.info('mount');
|
||||
const controller = new AbortController();
|
||||
const lists = Object.values(WorkspacePlugins)
|
||||
.sort((a, b) => a.loadPriority - b.loadPriority)
|
||||
.map(({ CRUD }) => CRUD.list);
|
||||
async function fetch() {
|
||||
const items = [];
|
||||
for (const list of lists) {
|
||||
try {
|
||||
const item = await list();
|
||||
items.push(...item.map(x => ({ id: x.id, flavour: x.flavour })));
|
||||
} catch (e) {
|
||||
logger.error('list data error:', e);
|
||||
}
|
||||
}
|
||||
if (controller.signal.aborted) {
|
||||
return;
|
||||
}
|
||||
set([...items]);
|
||||
logger.info('mount first data:', items);
|
||||
}
|
||||
fetch();
|
||||
return () => {
|
||||
controller.abort();
|
||||
logger.info('unmount');
|
||||
};
|
||||
}, [set]);
|
||||
const currentWorkspaceId = useAtomValue(currentWorkspaceIdAtom);
|
||||
return (
|
||||
<NoSsr>
|
||||
{/* fixme(himself65): don't re-render whole modals */}
|
||||
<ModalProvider key={currentWorkspaceId} />
|
||||
<Suspense fallback={<PageLoading />}>
|
||||
<WorkspaceLayoutInner>{children}</WorkspaceLayoutInner>
|
||||
</Suspense>
|
||||
</NoSsr>
|
||||
);
|
||||
};
|
||||
|
||||
export const WorkspaceLayout: React.FC<React.PropsWithChildren> = ({
|
||||
export const WorkspaceLayoutInner: React.FC<React.PropsWithChildren> = ({
|
||||
children,
|
||||
}) => {
|
||||
const { i18n } = useTranslation();
|
||||
useEffect(() => {
|
||||
document.documentElement.lang = i18n.language;
|
||||
// todo(himself65): this is a hack, we should use a better way to set the language
|
||||
setUpLanguage(i18n);
|
||||
}, [i18n]);
|
||||
useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
refreshDataCenter(controller.signal);
|
||||
return () => {
|
||||
controller.abort();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const [show, setShow] = useAtom(sideBarOpenAtom);
|
||||
useSyncWorkspaces();
|
||||
const [currentWorkspace] = useCurrentWorkspace();
|
||||
const [currentPageId] = useCurrentPageId();
|
||||
const workspaces = useWorkspaces();
|
||||
|
||||
useEffect(() => {
|
||||
console.log(workspaces);
|
||||
}, [workspaces]);
|
||||
|
||||
useEffect(() => {
|
||||
const providers = workspaces.flatMap(workspace =>
|
||||
workspace.providers.filter(provider => provider.background)
|
||||
@@ -91,7 +134,6 @@ export const WorkspaceLayout: React.FC<React.PropsWithChildren> = ({
|
||||
const isPublicWorkspace =
|
||||
router.pathname.split('/')[1] === 'public-workspace';
|
||||
const title = useRouterTitle(router);
|
||||
const [, setOpenQuickSearchModalAtom] = useAtom(openQuickSearchModalAtom);
|
||||
const handleOpenPage = useCallback(
|
||||
(pageId: string) => {
|
||||
assertExists(currentWorkspace);
|
||||
@@ -113,6 +155,10 @@ export const WorkspaceLayout: React.FC<React.PropsWithChildren> = ({
|
||||
const handleOpenWorkspaceListModal = useCallback(() => {
|
||||
setOpenWorkspacesModal(true);
|
||||
}, [setOpenWorkspacesModal]);
|
||||
|
||||
const [openQuickSearchModal, setOpenQuickSearchModalAtom] = useAtom(
|
||||
openQuickSearchModalAtom
|
||||
);
|
||||
const handleOpenQuickSearchModal = useCallback(() => {
|
||||
setOpenQuickSearchModalAtom(true);
|
||||
}, [setOpenQuickSearchModalAtom]);
|
||||
@@ -153,6 +199,14 @@ export const WorkspaceLayout: React.FC<React.PropsWithChildren> = ({
|
||||
</StyledToolWrapper>
|
||||
</StyledWrapper>
|
||||
</StyledPage>
|
||||
{currentWorkspace?.blockSuiteWorkspace && (
|
||||
<QuickSearchModal
|
||||
blockSuiteWorkspace={currentWorkspace?.blockSuiteWorkspace}
|
||||
open={openQuickSearchModal}
|
||||
setOpen={setOpenQuickSearchModalAtom}
|
||||
router={router}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user