From 83716c2fd9b99bf4cb7a306f99311b9319345d4f Mon Sep 17 00:00:00 2001 From: EYHN Date: Fri, 16 Aug 2024 09:12:18 +0000 Subject: [PATCH] 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 --- .../livedata/effect/__tests__/effect.spec.ts | 1 + .../src/modules/workspace/entities/list.ts | 9 +- .../modules/workspace/entities/workspace.ts | 4 - .../modules/workspace/providers/flavour.ts | 2 +- .../src/modules/workspace/scopes/workspace.ts | 4 +- .../src/modules/workspace/services/engine.ts | 5 +- .../src/modules/workspace/services/repo.ts | 15 +- .../share-menu/share-menu.tsx | 10 +- .../share-menu/share-page.tsx | 24 +-- .../page-list/use-filtered-page-metas.tsx | 10 +- .../view/edit-collection/select-page.tsx | 23 +- .../hooks/affine/use-all-page-list-config.tsx | 10 +- .../core/src/layouts/workspace-layout.tsx | 6 +- .../frontend/core/src/modules/cloud/error.ts | 10 +- .../core/src/modules/cloud/services/fetch.ts | 7 +- .../core/src/modules/docs-search/index.ts | 2 +- .../docs-search/services/docs-search.ts | 9 + .../explorer/views/nodes/collection/index.tsx | 12 +- .../modules/share-doc/entities/share-info.ts | 2 +- .../share-doc/entities/share-reader.ts | 66 ++++++ .../core/src/modules/share-doc/index.ts | 26 ++- .../{share-docs.ts => share-docs-list.ts} | 2 +- .../modules/share-doc/services/share-info.ts | 7 + .../share-doc/services/share-reader.ts | 7 + .../src/modules/share-doc/services/share.ts | 7 - .../modules/share-doc/stores/share-reader.ts | 42 ++++ .../modules/workspace-engine/impls/cloud.ts | 8 +- .../modules/workspace-engine/impls/local.ts | 2 +- .../src/modules/workspace-engine/index.ts | 2 + packages/frontend/core/src/pages/index.tsx | 2 +- .../core/src/pages/workspace/index.tsx | 146 +++++++++---- .../{ => workspace}/share/share-footer.css.ts | 0 .../{ => workspace}/share/share-footer.tsx | 0 .../{ => workspace}/share/share-header.css.ts | 0 .../{ => workspace}/share/share-header.tsx | 2 +- .../share/share-page.css.ts} | 0 .../share/share-page.tsx} | 203 +++++++----------- packages/frontend/core/src/router.tsx | 4 +- packages/frontend/graphql/src/error.ts | 7 + 39 files changed, 431 insertions(+), 267 deletions(-) create mode 100644 packages/frontend/core/src/modules/share-doc/entities/share-reader.ts rename packages/frontend/core/src/modules/share-doc/services/{share-docs.ts => share-docs-list.ts} (90%) create mode 100644 packages/frontend/core/src/modules/share-doc/services/share-info.ts create mode 100644 packages/frontend/core/src/modules/share-doc/services/share-reader.ts delete mode 100644 packages/frontend/core/src/modules/share-doc/services/share.ts create mode 100644 packages/frontend/core/src/modules/share-doc/stores/share-reader.ts rename packages/frontend/core/src/pages/{ => workspace}/share/share-footer.css.ts (100%) rename packages/frontend/core/src/pages/{ => workspace}/share/share-footer.tsx (100%) rename packages/frontend/core/src/pages/{ => workspace}/share/share-header.css.ts (100%) rename packages/frontend/core/src/pages/{ => workspace}/share/share-header.tsx (88%) rename packages/frontend/core/src/pages/{share/share-detail-page.css.ts => workspace/share/share-page.css.ts} (100%) rename packages/frontend/core/src/pages/{share/share-detail-page.tsx => workspace/share/share-page.tsx} (56%) diff --git a/packages/common/infra/src/livedata/effect/__tests__/effect.spec.ts b/packages/common/infra/src/livedata/effect/__tests__/effect.spec.ts index 969510baa1..75d8cbcff4 100644 --- a/packages/common/infra/src/livedata/effect/__tests__/effect.spec.ts +++ b/packages/common/infra/src/livedata/effect/__tests__/effect.spec.ts @@ -56,6 +56,7 @@ describe('example', () => { fetchUser.mockRejectedValue(new Error('some error')); loadUser(1); await vi.waitFor(() => expect(error$.value).toBeInstanceOf(Error)); + await vi.waitFor(() => expect(isLoading$.value).toBe(false)); }); test('isLoading', async () => { diff --git a/packages/common/infra/src/modules/workspace/entities/list.ts b/packages/common/infra/src/modules/workspace/entities/list.ts index 472149ca35..52f01c3333 100644 --- a/packages/common/infra/src/modules/workspace/entities/list.ts +++ b/packages/common/infra/src/modules/workspace/entities/list.ts @@ -11,8 +11,8 @@ export class WorkspaceList extends Entity { .map(workspaces => { return workspaces.flat(); }); - isLoading$ = new LiveData( - this.providers.map(p => p.isLoading$ ?? new LiveData(false)) + isRevalidating$ = new LiveData( + this.providers.map(p => p.isRevalidating$ ?? new LiveData(false)) ) .flat() .map(isLoadings => isLoadings.some(isLoading => isLoading)); @@ -24,4 +24,9 @@ export class WorkspaceList extends Entity { revalidate() { this.providers.forEach(provider => provider.revalidate?.()); } + + waitForRevalidation(signal?: AbortSignal) { + this.revalidate(); + return this.isRevalidating$.waitFor(isLoading => !isLoading, signal); + } } diff --git a/packages/common/infra/src/modules/workspace/entities/workspace.ts b/packages/common/infra/src/modules/workspace/entities/workspace.ts index 2695d3ca3f..e93525b73d 100644 --- a/packages/common/infra/src/modules/workspace/entities/workspace.ts +++ b/packages/common/infra/src/modules/workspace/entities/workspace.ts @@ -62,10 +62,6 @@ export class Workspace extends Entity { return this.framework.get(WorkspaceUpgradeService).upgrade; } - get flavourProvider() { - return this.scope.props.flavourProvider; - } - name$ = LiveData.from( new Observable(subscriber => { subscriber.next(this.docCollection.meta.name); diff --git a/packages/common/infra/src/modules/workspace/providers/flavour.ts b/packages/common/infra/src/modules/workspace/providers/flavour.ts index b12dd3250e..e00fd850e0 100644 --- a/packages/common/infra/src/modules/workspace/providers/flavour.ts +++ b/packages/common/infra/src/modules/workspace/providers/flavour.ts @@ -38,7 +38,7 @@ export interface WorkspaceFlavourProvider { /** * means the workspace list is loading. if it's true, the workspace page will show loading spinner. */ - isLoading$?: LiveData; + isRevalidating$?: LiveData; /** * revalidate the workspace list. diff --git a/packages/common/infra/src/modules/workspace/scopes/workspace.ts b/packages/common/infra/src/modules/workspace/scopes/workspace.ts index 9fae92f612..6371139231 100644 --- a/packages/common/infra/src/modules/workspace/scopes/workspace.ts +++ b/packages/common/infra/src/modules/workspace/scopes/workspace.ts @@ -1,10 +1,10 @@ import { Scope } from '../../../framework'; import type { WorkspaceOpenOptions } from '../open-options'; -import type { WorkspaceFlavourProvider } from '../providers/flavour'; +import type { WorkspaceEngineProvider } from '../providers/flavour'; export type { DocCollection } from '@blocksuite/store'; export class WorkspaceScope extends Scope<{ openOptions: WorkspaceOpenOptions; - flavourProvider: WorkspaceFlavourProvider; + engineProvider: WorkspaceEngineProvider; }> {} diff --git a/packages/common/infra/src/modules/workspace/services/engine.ts b/packages/common/infra/src/modules/workspace/services/engine.ts index d1be647d2f..8dcf8ec6dd 100644 --- a/packages/common/infra/src/modules/workspace/services/engine.ts +++ b/packages/common/infra/src/modules/workspace/services/engine.ts @@ -7,10 +7,7 @@ export class WorkspaceEngineService extends Service { get engine() { if (!this._engine) { this._engine = this.framework.createEntity(WorkspaceEngine, { - engineProvider: - this.workspaceScope.props.flavourProvider.getEngineProvider( - this.workspaceScope.props.openOptions.metadata.id - ), + engineProvider: this.workspaceScope.props.engineProvider, }); } return this._engine; diff --git a/packages/common/infra/src/modules/workspace/services/repo.ts b/packages/common/infra/src/modules/workspace/services/repo.ts index d8d4cb8461..a38652f079 100644 --- a/packages/common/infra/src/modules/workspace/services/repo.ts +++ b/packages/common/infra/src/modules/workspace/services/repo.ts @@ -6,7 +6,10 @@ import { ObjectPool } from '../../../utils'; import type { Workspace } from '../entities/workspace'; import { WorkspaceInitialized } from '../events'; import type { WorkspaceOpenOptions } from '../open-options'; -import type { WorkspaceFlavourProvider } from '../providers/flavour'; +import type { + WorkspaceEngineProvider, + WorkspaceFlavourProvider, +} from '../providers/flavour'; import { WorkspaceScope } from '../scopes/workspace'; import type { WorkspaceProfileService } from './profile'; import { WorkspaceService } from './workspace'; @@ -39,7 +42,7 @@ export class WorkspaceRepositoryService extends Service { */ open = ( options: WorkspaceOpenOptions, - customProvider?: WorkspaceFlavourProvider + customProvider?: WorkspaceEngineProvider ): { workspace: Workspace; dispose: () => void; @@ -76,14 +79,16 @@ export class WorkspaceRepositoryService extends Service { instantiate( openOptions: WorkspaceOpenOptions, - customProvider?: WorkspaceFlavourProvider + customProvider?: WorkspaceEngineProvider ) { logger.info( `open workspace [${openOptions.metadata.flavour}] ${openOptions.metadata.id} ` ); const provider = customProvider ?? - this.providers.find(p => p.flavour === openOptions.metadata.flavour); + this.providers + .find(p => p.flavour === openOptions.metadata.flavour) + ?.getEngineProvider(openOptions.metadata.id); if (!provider) { throw new Error( `Unknown workspace flavour: ${openOptions.metadata.flavour}` @@ -92,7 +97,7 @@ export class WorkspaceRepositoryService extends Service { const workspaceScope = this.framework.createScope(WorkspaceScope, { openOptions, - flavourProvider: provider, + engineProvider: provider, }); const workspace = workspaceScope.get(WorkspaceService).workspace; diff --git a/packages/frontend/core/src/components/affine/share-page-modal/share-menu/share-menu.tsx b/packages/frontend/core/src/components/affine/share-page-modal/share-menu/share-menu.tsx index 42fb69bdd7..897958bd89 100644 --- a/packages/frontend/core/src/components/affine/share-page-modal/share-menu/share-menu.tsx +++ b/packages/frontend/core/src/components/affine/share-page-modal/share-menu/share-menu.tsx @@ -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 ) { 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 (