refactor: public workspace (#996)

Co-authored-by: himself65 <himself65@outlook.com>
This commit is contained in:
Qi
2023-02-15 01:39:53 +08:00
committed by GitHub
parent 0370ec67df
commit 5a3e6aa041
5 changed files with 127 additions and 89 deletions

View File

@@ -0,0 +1,35 @@
import { getDataCenter, WorkspaceUnit } from '@affine/datacenter';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
export function useLoadPublicWorkspace(workspaceId: string) {
const router = useRouter();
const [workspace, setWorkspace] = useState<WorkspaceUnit | null>();
const [status, setStatus] = useState<'loading' | 'error' | 'success'>(
'loading'
);
useEffect(() => {
setStatus('loading');
const init = async () => {
const dataCenter = await getDataCenter();
dataCenter
.loadPublicWorkspace(workspaceId)
.then(data => {
setWorkspace(data);
setStatus('success');
})
.catch(() => {
// if (!cancel) {
// router.push('/404');
// }
setStatus('error');
});
};
init();
}, [router, workspaceId]);
return { status, workspace };
}

View File

@@ -1,31 +0,0 @@
import { useAppState } from '@/providers/app-state-provider';
import { WorkspaceUnit } from '@affine/datacenter';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
export function usePublicWorkspace(workspaceId: string) {
const { dataCenter } = useAppState();
const router = useRouter();
const [workspace, setWorkspace] = useState<WorkspaceUnit>();
useEffect(() => {
let cancel = false;
dataCenter
.loadPublicWorkspace(workspaceId)
.then(data => {
if (!cancel) {
setWorkspace(data);
}
})
.catch(() => {
if (!cancel) {
router.push('/404');
}
});
return () => {
cancel = true;
};
}, [router, workspaceId, dataCenter]);
return workspace;
}

View File

@@ -39,9 +39,16 @@ type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout;
};
// Page list which do not rely on app state
const NoNeedAppStatePageList = [
'/404',
'/public-workspace/[workspaceId]',
'/public-workspace/[workspaceId]/[pageId]',
];
const App = ({ Component, pageProps }: AppPropsWithLayout) => {
const getLayout = Component.getLayout || (page => page);
const { i18n } = useTranslation();
const router = useRouter();
React.useEffect(() => {
document.documentElement.lang = i18n.language;
@@ -68,7 +75,11 @@ const App = ({ Component, pageProps }: AppPropsWithLayout) => {
<ConfirmProvider key="ConfirmProvider" />,
]}
>
<AppDefender>{getLayout(<Component {...pageProps} />)}</AppDefender>
{NoNeedAppStatePageList.includes(router.route) ? (
getLayout(<Component {...pageProps} />)
) : (
<AppDefender>{getLayout(<Component {...pageProps} />)}</AppDefender>
)}
</ProviderComposer>
</>
);
@@ -84,11 +95,6 @@ const AppDefender = ({ children }: PropsWithChildren) => {
}
}, [router]);
// if you visit /404, you will see the children directly
if (router.route === '/404') {
return <div>{children}</div>;
}
return <div>{synced ? children : <PageLoading />}</div>;
};

View File

@@ -10,7 +10,7 @@ import NextLink from 'next/link';
import { PaperIcon, SearchIcon } from '@blocksuite/icons';
import { WorkspaceUnitAvatar } from '@/components/workspace-avatar';
import { useModal } from '@/store/globalModal';
import { usePublicWorkspace } from '@/hooks/use-public-workspace';
import { useLoadPublicWorkspace } from '@/hooks/use-load-public-workspace';
import { useTranslation } from '@affine/i18n';
const DynamicBlocksuite = dynamic(() => import('@/components/editor'), {
@@ -20,8 +20,9 @@ const DynamicBlocksuite = dynamic(() => import('@/components/editor'), {
const Page: NextPageWithLayout = () => {
const router = useRouter();
const { workspaceId, pageId } = router.query as Record<string, string>;
const workspaceUnit = usePublicWorkspace(workspaceId);
const [loaded, setLoaded] = useState(false);
const { status, workspace: workspaceUnit } =
useLoadPublicWorkspace(workspaceId);
const [editorLoaded, setEditorLoaded] = useState(false);
const { triggerQuickSearchModal } = useModal();
const { t } = useTranslation();
@@ -43,48 +44,58 @@ const Page: NextPageWithLayout = () => {
}
}, [workspace, router, pageId]);
return (
<>
{!loaded && <PageLoading />}
<PageContainer>
<NavContainer>
<Breadcrumbs>
<StyledBreadcrumbs href={`/public-workspace/${workspaceId}`}>
<WorkspaceUnitAvatar
size={24}
name={workspaceName}
workspaceUnit={workspaceUnit}
/>
<span>{workspaceName}</span>
</StyledBreadcrumbs>
<StyledBreadcrumbs
href={`/public-workspace/${workspaceId}/${pageId}`}
>
<PaperIcon fontSize={24} />
<span>{pageTitle ? pageTitle : t('Untitled')}</span>
</StyledBreadcrumbs>
</Breadcrumbs>
<SearchButton
onClick={() => {
triggerQuickSearchModal();
}}
>
<SearchIcon />
</SearchButton>
</NavContainer>
useEffect(() => {
if (status === 'error') {
router.push('/404');
}
}, [router, status]);
{workspace && page && (
<DynamicBlocksuite
page={page}
workspace={workspace}
setEditor={editor => {
editor.readonly = true;
setLoaded(true);
}}
/>
)}
</PageContainer>
</>
if (status === 'loading' || !editorLoaded) {
return <PageLoading />;
}
if (status === 'error') {
return null;
}
return (
<PageContainer>
<NavContainer>
<Breadcrumbs>
<StyledBreadcrumbs href={`/public-workspace/${workspaceId}`}>
<WorkspaceUnitAvatar
size={24}
name={workspaceName}
workspaceUnit={workspaceUnit}
/>
<span>{workspaceName}</span>
</StyledBreadcrumbs>
<StyledBreadcrumbs
href={`/public-workspace/${workspaceId}/${pageId}`}
>
<PaperIcon fontSize={24} />
<span>{pageTitle ? pageTitle : t('Untitled')}</span>
</StyledBreadcrumbs>
</Breadcrumbs>
<SearchButton
onClick={() => {
triggerQuickSearchModal();
}}
>
<SearchIcon />
</SearchButton>
</NavContainer>
{workspace && page && (
<DynamicBlocksuite
page={page}
workspace={workspace}
setEditor={editor => {
editor.readonly = true;
setEditorLoaded(true);
}}
/>
)}
</PageContainer>
);
};

View File

@@ -1,30 +1,47 @@
import { PageList } from '@/components/page-list';
import { WorkspaceUnitAvatar } from '@/components/workspace-avatar';
import { usePublicWorkspace } from '@/hooks/use-public-workspace';
import { useLoadPublicWorkspace } from '@/hooks/use-load-public-workspace';
import { PageMeta } from '@/providers/app-state-provider';
import { useModal } from '@/store/globalModal';
import { Breadcrumbs } from '@affine/component';
import { SearchIcon } from '@blocksuite/icons';
import { useRouter } from 'next/router';
import { ReactElement, useMemo } from 'react';
import { ReactElement, useMemo, useEffect } from 'react';
import {
NavContainer,
PageContainer,
SearchButton,
StyledBreadcrumbs,
} from './[pageId]';
import { PageLoading } from '@/components/loading';
const All = () => {
const router = useRouter();
const { triggerQuickSearchModal } = useModal();
const workspaceUnit = usePublicWorkspace(router.query.workspaceId as string);
const { status, workspace } = useLoadPublicWorkspace(
router.query.workspaceId as string
);
const pageList = useMemo(() => {
return (workspaceUnit?.blocksuiteWorkspace?.meta.pageMetas ??
[]) as PageMeta[];
}, [workspaceUnit]);
return (workspace?.blocksuiteWorkspace?.meta.pageMetas ?? []) as PageMeta[];
}, [workspace]);
const workspaceName = workspace?.blocksuiteWorkspace?.meta.name;
useEffect(() => {
if (status === 'error') {
router.push('/404');
}
}, [router, status]);
if (status === 'loading') {
return <PageLoading />;
}
if (status === 'error') {
return null;
}
const workspaceName = workspaceUnit?.blocksuiteWorkspace?.meta.name;
return (
<PageContainer>
<NavContainer>
@@ -35,7 +52,7 @@ const All = () => {
<WorkspaceUnitAvatar
size={24}
name={workspaceName}
workspaceUnit={workspaceUnit}
workspaceUnit={workspace}
/>
<span>{workspaceName}</span>
</StyledBreadcrumbs>