feat(core): share in workspace link (#7897)

ShareDocsService -> ShareDocsListService
ShareService -> ShareInfoService
(*new) ShareReaderService

`/share/:workspaceId/:docId` -> redirect to -> `/workspace/:workspaceId/:docId`

workspace loading process

1. find workspace in workspace list
2. (if not found) revalidate workspace list
3. (if still not found) try load share page
4. (if share page found) => share page
5. (if share page not found) => 404
6. (if workspace found) => workspace page
This commit is contained in:
EYHN
2024-08-16 09:12:18 +00:00
parent 620d20710a
commit 83716c2fd9
39 changed files with 431 additions and 267 deletions
@@ -1,7 +1,7 @@
import { Button } from '@affine/component/ui/button';
import { Divider } from '@affine/component/ui/divider';
import { Menu } from '@affine/component/ui/menu';
import { ShareService } from '@affine/core/modules/share-doc';
import { ShareInfoService } from '@affine/core/modules/share-doc';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { useI18n } from '@affine/i18n';
import { WebIcon } from '@blocksuite/icons/rc';
@@ -48,12 +48,12 @@ const DefaultShareButton = forwardRef(function DefaultShareButton(
ref: Ref<HTMLButtonElement>
) {
const t = useI18n();
const shareService = useService(ShareService);
const shared = useLiveData(shareService.share.isShared$);
const shareInfoService = useService(ShareInfoService);
const shared = useLiveData(shareInfoService.shareInfo.isShared$);
useEffect(() => {
shareService.share.revalidate();
}, [shareService]);
shareInfoService.shareInfo.revalidate();
}, [shareInfoService]);
return (
<Button ref={ref} className={styles.shareButton} variant="primary">
@@ -6,7 +6,7 @@ import { useSharingUrl } from '@affine/core/hooks/affine/use-share-url';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { track } from '@affine/core/mixpanel';
import { ServerConfigService } from '@affine/core/modules/cloud';
import { ShareService } from '@affine/core/modules/share-doc';
import { ShareInfoService } from '@affine/core/modules/share-doc';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { PublicPageMode } from '@affine/graphql';
import { useI18n } from '@affine/i18n';
@@ -59,13 +59,13 @@ export const AffineSharePage = (props: ShareMenuProps) => {
workspaceMetadata: { id: workspaceId },
} = props;
const doc = useService(DocService).doc;
const shareService = useService(ShareService);
const shareInfoService = useService(ShareInfoService);
const serverConfig = useService(ServerConfigService).serverConfig;
useEffect(() => {
shareService.share.revalidate();
}, [shareService]);
const isSharedPage = useLiveData(shareService.share.isShared$);
const sharedMode = useLiveData(shareService.share.sharedMode$);
shareInfoService.shareInfo.revalidate();
}, [shareInfoService]);
const isSharedPage = useLiveData(shareInfoService.shareInfo.isShared$);
const sharedMode = useLiveData(shareInfoService.shareInfo.sharedMode$);
const baseUrl = useLiveData(serverConfig.config$.map(c => c?.baseUrl));
const isLoading =
isSharedPage === null || sharedMode === null || baseUrl === null;
@@ -103,7 +103,7 @@ export const AffineSharePage = (props: ShareMenuProps) => {
const onClickCreateLink = useAsyncCallback(async () => {
try {
await shareService.share.enableShare(
await shareInfoService.shareInfo.enableShare(
mode === 'edgeless' ? PublicPageMode.Edgeless : PublicPageMode.Page
);
track.$.sharePanel.$.createShareLink({
@@ -139,11 +139,11 @@ export const AffineSharePage = (props: ShareMenuProps) => {
});
console.error(err);
}
}, [mode, shareService.share, sharingUrl, t]);
}, [mode, shareInfoService.shareInfo, sharingUrl, t]);
const onDisablePublic = useAsyncCallback(async () => {
try {
await shareService.share.disableShare();
await shareInfoService.shareInfo.disableShare();
notify.error({
title:
t[
@@ -168,13 +168,13 @@ export const AffineSharePage = (props: ShareMenuProps) => {
console.log(err);
}
setShowDisable(false);
}, [shareService, t]);
}, [shareInfoService, t]);
const onShareModeChange = useAsyncCallback(
async (value: DocMode) => {
try {
if (isSharedPage) {
await shareService.share.changeShare(
await shareInfoService.shareInfo.changeShare(
value === 'edgeless' ? PublicPageMode.Edgeless : PublicPageMode.Page
);
notify.success({
@@ -208,7 +208,7 @@ export const AffineSharePage = (props: ShareMenuProps) => {
console.error(err);
}
},
[isSharedPage, shareService.share, t]
[isSharedPage, shareInfoService.shareInfo, t]
);
if (isLoading) {
@@ -1,5 +1,5 @@
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
import { ShareDocsService } from '@affine/core/modules/share-doc';
import { ShareDocsListService } from '@affine/core/modules/share-doc';
import type { Collection, Filter } from '@affine/env/filter';
import { PublicPageMode } from '@affine/graphql';
import type { DocMeta } from '@blocksuite/store';
@@ -16,8 +16,8 @@ export const useFilteredPageMetas = (
collection?: Collection;
} = {}
) => {
const shareDocsService = useService(ShareDocsService);
const shareDocs = useLiveData(shareDocsService.shareDocs?.list$);
const shareDocsListService = useService(ShareDocsListService);
const shareDocs = useLiveData(shareDocsListService.shareDocs?.list$);
const getPublicMode = useCallback(
(id: string) => {
@@ -33,8 +33,8 @@ export const useFilteredPageMetas = (
useEffect(() => {
// TODO(@eyhn): loading & error UI
shareDocsService.shareDocs?.revalidate();
}, [shareDocsService]);
shareDocsListService.shareDocs?.revalidate();
}, [shareDocsListService]);
const favAdapter = useService(CompatibleFavoriteItemsAdapter);
const favoriteItems = useLiveData(favAdapter.favorites$);
@@ -1,7 +1,7 @@
import { IconButton, Menu, toast } from '@affine/component';
import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
import { ShareDocsService } from '@affine/core/modules/share-doc';
import { ShareDocsListService } from '@affine/core/modules/share-doc';
import { PublicPageMode } from '@affine/graphql';
import { Trans, useI18n } from '@affine/i18n';
import { FilterIcon } from '@blocksuite/icons/rc';
@@ -56,21 +56,24 @@ export const SelectPage = ({
const clearSelected = useCallback(() => {
onChange([]);
}, [onChange]);
const { workspaceService, compatibleFavoriteItemsAdapter, shareDocsService } =
useServices({
ShareDocsService,
WorkspaceService,
CompatibleFavoriteItemsAdapter,
});
const shareDocs = useLiveData(shareDocsService.shareDocs?.list$);
const {
workspaceService,
compatibleFavoriteItemsAdapter,
shareDocsListService,
} = useServices({
ShareDocsListService,
WorkspaceService,
CompatibleFavoriteItemsAdapter,
});
const shareDocs = useLiveData(shareDocsListService.shareDocs?.list$);
const workspace = workspaceService.workspace;
const docCollection = workspace.docCollection;
const pageMetas = useBlockSuiteDocMeta(docCollection);
const favourites = useLiveData(compatibleFavoriteItemsAdapter.favorites$);
useEffect(() => {
shareDocsService.shareDocs?.revalidate();
}, [shareDocsService.shareDocs]);
shareDocsListService.shareDocs?.revalidate();
}, [shareDocsListService.shareDocs]);
const getPublicMode = useCallback(
(id: string) => {