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

View File

@@ -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 () => {

View File

@@ -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);
}
}

View File

@@ -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<string | undefined>(
new Observable(subscriber => {
subscriber.next(this.docCollection.meta.name);

View File

@@ -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<boolean>;
isRevalidating$?: LiveData<boolean>;
/**
* revalidate the workspace list.

View File

@@ -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;
}> {}

View File

@@ -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;

View File

@@ -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;