refactor: public workspace (#996)
Co-authored-by: himself65 <himself65@outlook.com>
This commit is contained in:
35
apps/web/src/hooks/use-load-public-workspace.ts
Normal file
35
apps/web/src/hooks/use-load-public-workspace.ts
Normal 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 };
|
||||||
|
}
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -39,9 +39,16 @@ type AppPropsWithLayout = AppProps & {
|
|||||||
Component: NextPageWithLayout;
|
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 App = ({ Component, pageProps }: AppPropsWithLayout) => {
|
||||||
const getLayout = Component.getLayout || (page => page);
|
const getLayout = Component.getLayout || (page => page);
|
||||||
const { i18n } = useTranslation();
|
const { i18n } = useTranslation();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
document.documentElement.lang = i18n.language;
|
document.documentElement.lang = i18n.language;
|
||||||
@@ -68,7 +75,11 @@ const App = ({ Component, pageProps }: AppPropsWithLayout) => {
|
|||||||
<ConfirmProvider key="ConfirmProvider" />,
|
<ConfirmProvider key="ConfirmProvider" />,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
|
{NoNeedAppStatePageList.includes(router.route) ? (
|
||||||
|
getLayout(<Component {...pageProps} />)
|
||||||
|
) : (
|
||||||
<AppDefender>{getLayout(<Component {...pageProps} />)}</AppDefender>
|
<AppDefender>{getLayout(<Component {...pageProps} />)}</AppDefender>
|
||||||
|
)}
|
||||||
</ProviderComposer>
|
</ProviderComposer>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@@ -84,11 +95,6 @@ const AppDefender = ({ children }: PropsWithChildren) => {
|
|||||||
}
|
}
|
||||||
}, [router]);
|
}, [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>;
|
return <div>{synced ? children : <PageLoading />}</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import NextLink from 'next/link';
|
|||||||
import { PaperIcon, SearchIcon } from '@blocksuite/icons';
|
import { PaperIcon, SearchIcon } from '@blocksuite/icons';
|
||||||
import { WorkspaceUnitAvatar } from '@/components/workspace-avatar';
|
import { WorkspaceUnitAvatar } from '@/components/workspace-avatar';
|
||||||
import { useModal } from '@/store/globalModal';
|
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';
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
|
||||||
const DynamicBlocksuite = dynamic(() => import('@/components/editor'), {
|
const DynamicBlocksuite = dynamic(() => import('@/components/editor'), {
|
||||||
@@ -20,8 +20,9 @@ const DynamicBlocksuite = dynamic(() => import('@/components/editor'), {
|
|||||||
const Page: NextPageWithLayout = () => {
|
const Page: NextPageWithLayout = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceId, pageId } = router.query as Record<string, string>;
|
const { workspaceId, pageId } = router.query as Record<string, string>;
|
||||||
const workspaceUnit = usePublicWorkspace(workspaceId);
|
const { status, workspace: workspaceUnit } =
|
||||||
const [loaded, setLoaded] = useState(false);
|
useLoadPublicWorkspace(workspaceId);
|
||||||
|
const [editorLoaded, setEditorLoaded] = useState(false);
|
||||||
const { triggerQuickSearchModal } = useModal();
|
const { triggerQuickSearchModal } = useModal();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@@ -43,9 +44,20 @@ const Page: NextPageWithLayout = () => {
|
|||||||
}
|
}
|
||||||
}, [workspace, router, pageId]);
|
}, [workspace, router, pageId]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (status === 'error') {
|
||||||
|
router.push('/404');
|
||||||
|
}
|
||||||
|
}, [router, status]);
|
||||||
|
|
||||||
|
if (status === 'loading' || !editorLoaded) {
|
||||||
|
return <PageLoading />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'error') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
{!loaded && <PageLoading />}
|
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<NavContainer>
|
<NavContainer>
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
@@ -79,12 +91,11 @@ const Page: NextPageWithLayout = () => {
|
|||||||
workspace={workspace}
|
workspace={workspace}
|
||||||
setEditor={editor => {
|
setEditor={editor => {
|
||||||
editor.readonly = true;
|
editor.readonly = true;
|
||||||
setLoaded(true);
|
setEditorLoaded(true);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +1,47 @@
|
|||||||
import { PageList } from '@/components/page-list';
|
import { PageList } from '@/components/page-list';
|
||||||
import { WorkspaceUnitAvatar } from '@/components/workspace-avatar';
|
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 { PageMeta } from '@/providers/app-state-provider';
|
||||||
import { useModal } from '@/store/globalModal';
|
import { useModal } from '@/store/globalModal';
|
||||||
import { Breadcrumbs } from '@affine/component';
|
import { Breadcrumbs } from '@affine/component';
|
||||||
import { SearchIcon } from '@blocksuite/icons';
|
import { SearchIcon } from '@blocksuite/icons';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { ReactElement, useMemo } from 'react';
|
import { ReactElement, useMemo, useEffect } from 'react';
|
||||||
import {
|
import {
|
||||||
NavContainer,
|
NavContainer,
|
||||||
PageContainer,
|
PageContainer,
|
||||||
SearchButton,
|
SearchButton,
|
||||||
StyledBreadcrumbs,
|
StyledBreadcrumbs,
|
||||||
} from './[pageId]';
|
} from './[pageId]';
|
||||||
|
import { PageLoading } from '@/components/loading';
|
||||||
|
|
||||||
const All = () => {
|
const All = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { triggerQuickSearchModal } = useModal();
|
const { triggerQuickSearchModal } = useModal();
|
||||||
const workspaceUnit = usePublicWorkspace(router.query.workspaceId as string);
|
const { status, workspace } = useLoadPublicWorkspace(
|
||||||
|
router.query.workspaceId as string
|
||||||
|
);
|
||||||
|
|
||||||
const pageList = useMemo(() => {
|
const pageList = useMemo(() => {
|
||||||
return (workspaceUnit?.blocksuiteWorkspace?.meta.pageMetas ??
|
return (workspace?.blocksuiteWorkspace?.meta.pageMetas ?? []) as PageMeta[];
|
||||||
[]) as PageMeta[];
|
}, [workspace]);
|
||||||
}, [workspaceUnit]);
|
|
||||||
|
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 (
|
return (
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<NavContainer>
|
<NavContainer>
|
||||||
@@ -35,7 +52,7 @@ const All = () => {
|
|||||||
<WorkspaceUnitAvatar
|
<WorkspaceUnitAvatar
|
||||||
size={24}
|
size={24}
|
||||||
name={workspaceName}
|
name={workspaceName}
|
||||||
workspaceUnit={workspaceUnit}
|
workspaceUnit={workspace}
|
||||||
/>
|
/>
|
||||||
<span>{workspaceName}</span>
|
<span>{workspaceName}</span>
|
||||||
</StyledBreadcrumbs>
|
</StyledBreadcrumbs>
|
||||||
|
|||||||
Reference in New Issue
Block a user