feat(core): add blocksuite writer info service (#10754)

This commit is contained in:
EYHN
2025-03-12 05:02:04 +00:00
parent 0df8e31698
commit 4b5d1de206
11 changed files with 96 additions and 75 deletions

View File

@@ -7,7 +7,7 @@ import {
type PageEditor,
} from '@affine/core/blocksuite/editors';
import { useEnableAI } from '@affine/core/components/hooks/affine/use-enable-ai';
import { AuthService, PublicUserService } from '@affine/core/modules/cloud';
import { PublicUserService } from '@affine/core/modules/cloud';
import type { DocCustomPropertyInfo } from '@affine/core/modules/db';
import { DocService, DocsService } from '@affine/core/modules/doc';
import type {
@@ -94,7 +94,6 @@ const usePatchSpecs = (mode: DocMode) => {
featureFlagService,
memberSearchService,
publicUserService,
authService,
} = useServices({
PeekViewService,
DocService,
@@ -104,7 +103,6 @@ const usePatchSpecs = (mode: DocMode) => {
FeatureFlagService,
MemberSearchService,
PublicUserService,
AuthService,
});
const isCloud = workspaceService.workspace.flavour !== 'local';
const framework = useFramework();
@@ -167,7 +165,7 @@ const usePatchSpecs = (mode: DocMode) => {
isCloud
? [
patchUserListExtensions(memberSearchService),
patchUserExtensions(publicUserService, authService),
patchUserExtensions(publicUserService),
]
: [],
mode === 'edgeless' && enableTurboRenderer
@@ -201,7 +199,6 @@ const usePatchSpecs = (mode: DocMode) => {
isCloud,
memberSearchService,
publicUserService,
authService,
enableTurboRenderer,
featureFlagService.flags.enable_pdf_embed_preview.value,
]);

View File

@@ -1,24 +1,8 @@
import type {
AuthService,
PublicUserService,
} from '@affine/core/modules/cloud';
import type { PublicUserService } from '@affine/core/modules/cloud';
import { UserServiceExtension } from '@blocksuite/affine/shared/services';
export function patchUserExtensions(
publicUserService: PublicUserService,
authService: AuthService
) {
export function patchUserExtensions(publicUserService: PublicUserService) {
return UserServiceExtension({
getCurrentUser() {
const account = authService.session.account$.value;
return account
? {
id: account.id,
avatar: account.avatar,
name: account.label,
}
: null;
},
// eslint-disable-next-line rxjs/finnish
userInfo$(id) {
return publicUserService.publicUser$(id).signal;

View File

@@ -33,7 +33,6 @@ import { type Framework } from '@toeverything/infra';
import { DocScope } from '../doc/scopes/doc';
import { DocService } from '../doc/services/doc';
import { EditorScope } from '../editor';
import { GlobalCache, GlobalState } from '../storage/providers/global';
import { GlobalStateService } from '../storage/services/global';
import { UrlService } from '../url';
@@ -55,10 +54,10 @@ import { ValidatorProvider } from './provider/validator';
import { ServerScope } from './scopes/server';
import { AcceptInviteService } from './services/accept-invite';
import { AuthService } from './services/auth';
import { BlocksuiteWriterInfoService } from './services/blocksuite-writer-info';
import { CaptchaService } from './services/captcha';
import { CloudDocMetaService } from './services/cloud-doc-meta';
import { DefaultServerService } from './services/default-server';
import { EditorUserCursorLabelService } from './services/editor-user-cursor-label';
import { EventSourceService } from './services/eventsource';
import { FetchService } from './services/fetch';
import { GraphQLService } from './services/graphql';
@@ -167,11 +166,6 @@ export function configureCloudModule(framework: Framework) {
.service(WorkspaceInvoicesService)
.entity(WorkspaceInvoices, [WorkspaceService, WorkspaceServerService])
.service(SelfhostLicenseService, [SelfhostLicenseStore, WorkspaceService])
.store(SelfhostLicenseStore, [WorkspaceServerService]);
framework
.scope(WorkspaceScope)
.scope(DocScope)
.scope(EditorScope)
.service(EditorUserCursorLabelService, [WorkspaceServerService]);
.store(SelfhostLicenseStore, [WorkspaceServerService])
.service(BlocksuiteWriterInfoService, [WorkspaceServerService]);
}

View File

@@ -0,0 +1,46 @@
import { WriterInfoServiceExtension } from '@blocksuite/affine/shared/services';
import { OnEvent, Service } from '@toeverything/infra';
import { type Workspace, WorkspaceInitialized } from '../../workspace';
import type { DocImpl } from '../../workspace/impls/doc';
import type { WorkspaceServerService } from './workspace-server';
/**
* This service is used to set the writer info for the blocksuite editor.
*/
@OnEvent(WorkspaceInitialized, i => i.onWorkspaceInitialized)
export class BlocksuiteWriterInfoService extends Service {
constructor(private readonly workspaceServerService: WorkspaceServerService) {
super();
}
onWorkspaceInitialized(workspace: Workspace) {
const setWriterInfo = (doc: DocImpl) => {
const account = this.workspaceServerService.server?.account$.value;
doc.awarenessStore.awareness.setLocalStateField('user', {
name: account?.label,
});
doc.storeExtensions.push(
WriterInfoServiceExtension({
getWriterInfo: () => {
if (!account) {
return null;
}
return {
id: account.id,
name: account.label,
avatar: account.avatar,
};
},
})
);
};
const subscription = workspace.docCollection.meta.docMetaAdded.subscribe(
docId => {
const doc = workspace.docCollection.docs.get(docId) as DocImpl;
setWriterInfo(doc);
}
);
this.disposables.push(() => subscription.unsubscribe.bind(subscription));
}
}

View File

@@ -1,27 +0,0 @@
import { OnEvent, Service } from '@toeverything/infra';
import type { Editor } from '../../editor';
import { EditorInitialized } from '../../editor/events';
import type { WorkspaceServerService } from './workspace-server';
@OnEvent(EditorInitialized, i => i.onEditorInitialized)
export class EditorUserCursorLabelService extends Service {
constructor(private readonly workspaceServerService: WorkspaceServerService) {
super();
}
onEditorInitialized(editor: Editor) {
if (this.workspaceServerService.server) {
const subscription =
this.workspaceServerService.server.account$.subscribe(account => {
editor.doc.blockSuiteDoc.awarenessStore.awareness.setLocalStateField(
'user',
{
name: account?.label,
}
);
});
this.disposables.push(() => subscription.unsubscribe());
}
}
}

View File

@@ -2,6 +2,7 @@ import { SpecProvider } from '@blocksuite/affine/shared/utils';
import {
AwarenessStore,
type Doc,
type ExtensionType,
type GetBlocksOptions,
type Query,
Store,
@@ -92,6 +93,8 @@ export class DocImpl implements Doc {
*/
protected readonly _ySpaceDoc: Y.Doc;
readonly storeExtensions: ExtensionType[] = [];
readonly awarenessStore: AwarenessStore;
readonly id: string;
@@ -284,7 +287,9 @@ export class DocImpl implements Doc {
const storeExtensions = SpecProvider._.getSpec('store');
const extensionSet = new Set(
storeExtensions.value.concat(extensions ?? [])
storeExtensions.value
.concat(extensions ?? [])
.concat(this.storeExtensions)
);
const doc = new Store({

View File

@@ -110,7 +110,7 @@ export class WorkspaceRepositoryService extends Service {
workspace.engine.start();
this.framework.emitEvent(WorkspaceInitialized, workspace);
workspaceScope.emitEvent(WorkspaceInitialized, workspace);
flavourProvider?.onWorkspaceInitialized?.(workspace);