mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-17 01:56:27 +08:00
feat(editor): replace slot with rxjs subject (#10768)
This commit is contained in:
@@ -52,7 +52,7 @@ export class AuthService extends Service {
|
||||
skip(1) // skip the initial value
|
||||
)
|
||||
.subscribe(({ account }) => {
|
||||
AIProvider.slots.userInfo.emit(toAIUserInfo(account));
|
||||
AIProvider.slots.userInfo.next(toAIUserInfo(account));
|
||||
|
||||
if (account === null) {
|
||||
this.eventBus.emit(AccountLoggedOut, account);
|
||||
|
||||
@@ -17,7 +17,7 @@ export class EditorSettingService extends Service {
|
||||
onWorkspaceInitialized(workspace: Workspace) {
|
||||
// set default mode for new doc
|
||||
|
||||
workspace.docCollection.slots.docCreated.on(docId => {
|
||||
workspace.docCollection.slots.docCreated.subscribe(docId => {
|
||||
const preferMode = this.editorSetting.settings$.value.newDocDefaultMode;
|
||||
const docsService = workspace.scope.get(DocsService);
|
||||
const mode = preferMode === 'ask' ? 'page' : preferMode;
|
||||
|
||||
@@ -261,7 +261,9 @@ export class Editor extends Entity {
|
||||
scrollViewport?.removeEventListener('scroll', saveScrollPosition);
|
||||
});
|
||||
if (gfx) {
|
||||
unsubs.push(gfx.viewport.viewportUpdated.on(saveScrollPosition).dispose);
|
||||
const subscription =
|
||||
gfx.viewport.viewportUpdated.subscribe(saveScrollPosition);
|
||||
unsubs.push(subscription.unsubscribe.bind(subscription));
|
||||
}
|
||||
|
||||
// update selection when focusAt$ changed
|
||||
|
||||
@@ -9,11 +9,8 @@ import { EditorService } from '@affine/core/modules/editor';
|
||||
import { GuardService } from '@affine/core/modules/permissions';
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/affine/block-std/gfx';
|
||||
import { DisposableGroup } from '@blocksuite/affine/global/disposable';
|
||||
import { Bound } from '@blocksuite/affine/global/gfx';
|
||||
import {
|
||||
type Disposable,
|
||||
DisposableGroup,
|
||||
} from '@blocksuite/affine/global/slot';
|
||||
import { RefNodeSlotsProvider } from '@blocksuite/affine/rich-text';
|
||||
import {
|
||||
FrameworkScope,
|
||||
@@ -23,6 +20,7 @@ import {
|
||||
} from '@toeverything/infra';
|
||||
import clsx from 'clsx';
|
||||
import { lazy, Suspense, useCallback, useEffect } from 'react';
|
||||
import type { Subscription } from 'rxjs';
|
||||
|
||||
import { WorkbenchService } from '../../../workbench';
|
||||
import type { DocReferenceInfo } from '../../entities/peek-view';
|
||||
@@ -101,7 +99,7 @@ function DocPeekPreviewEditor({
|
||||
// doc change event inside peek view should be handled by peek view
|
||||
disposableGroup.add(
|
||||
// todo(@pengx17): seems not working
|
||||
refNodeSlots.docLinkClicked.on(options => {
|
||||
refNodeSlots.docLinkClicked.subscribe(options => {
|
||||
if (options.host !== editorContainer.host) {
|
||||
return;
|
||||
}
|
||||
@@ -129,7 +127,7 @@ function DocPeekPreviewEditor({
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const disposables: Disposable[] = [];
|
||||
const disposables: Subscription[] = [];
|
||||
const openHandler = () => {
|
||||
if (doc) {
|
||||
workbench.openDoc(doc.id);
|
||||
@@ -137,9 +135,13 @@ function DocPeekPreviewEditor({
|
||||
// chat panel open is already handled in <DetailPageImpl />
|
||||
}
|
||||
};
|
||||
disposables.push(AIProvider.slots.requestOpenWithChat.on(openHandler));
|
||||
disposables.push(AIProvider.slots.requestSendWithChat.on(openHandler));
|
||||
return () => disposables.forEach(d => d.dispose());
|
||||
disposables.push(
|
||||
AIProvider.slots.requestOpenWithChat.subscribe(openHandler)
|
||||
);
|
||||
disposables.push(
|
||||
AIProvider.slots.requestSendWithChat.subscribe(openHandler)
|
||||
);
|
||||
return () => disposables.forEach(d => d.unsubscribe());
|
||||
}, [doc, peekView, workbench, workspace.id]);
|
||||
|
||||
const openOutlinePanel = useCallback(() => {
|
||||
|
||||
@@ -23,8 +23,10 @@ export class TagStore extends Store {
|
||||
|
||||
subscribe(cb: () => void) {
|
||||
const disposable =
|
||||
this.workspaceService.workspace.docCollection.slots.docListUpdated.on(cb);
|
||||
return disposable.dispose;
|
||||
this.workspaceService.workspace.docCollection.slots.docListUpdated.subscribe(
|
||||
cb
|
||||
);
|
||||
return disposable.unsubscribe.bind(disposable);
|
||||
}
|
||||
|
||||
constructor(private readonly workspaceService: WorkspaceService) {
|
||||
|
||||
@@ -73,9 +73,11 @@ export class Workspace extends Entity {
|
||||
name$ = LiveData.from<string | undefined>(
|
||||
new Observable(subscriber => {
|
||||
subscriber.next(this.docCollection.meta.name);
|
||||
return this.docCollection.meta.commonFieldsUpdated.on(() => {
|
||||
subscriber.next(this.docCollection.meta.name);
|
||||
}).dispose;
|
||||
const subscription =
|
||||
this.docCollection.meta.commonFieldsUpdated.subscribe(() => {
|
||||
subscriber.next(this.docCollection.meta.name);
|
||||
});
|
||||
return subscription.unsubscribe.bind(subscription);
|
||||
}),
|
||||
undefined
|
||||
);
|
||||
@@ -83,9 +85,11 @@ export class Workspace extends Entity {
|
||||
avatar$ = LiveData.from<string | undefined>(
|
||||
new Observable(subscriber => {
|
||||
subscriber.next(this.docCollection.meta.avatar);
|
||||
return this.docCollection.meta.commonFieldsUpdated.on(() => {
|
||||
subscriber.next(this.docCollection.meta.avatar);
|
||||
}).dispose;
|
||||
const subscription =
|
||||
this.docCollection.meta.commonFieldsUpdated.subscribe(() => {
|
||||
subscriber.next(this.docCollection.meta.avatar);
|
||||
});
|
||||
return subscription.unsubscribe.bind(subscription);
|
||||
}),
|
||||
undefined
|
||||
);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Slot } from '@blocksuite/affine/global/slot';
|
||||
import { SpecProvider } from '@blocksuite/affine/shared/utils';
|
||||
import {
|
||||
AwarenessStore,
|
||||
@@ -10,6 +9,7 @@ import {
|
||||
type YBlock,
|
||||
} from '@blocksuite/affine/store';
|
||||
import { signal } from '@preact/signals-core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { Awareness } from 'y-protocols/awareness.js';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
@@ -37,7 +37,7 @@ export class DocImpl implements Doc {
|
||||
|
||||
private readonly _historyObserver = () => {
|
||||
this._updateCanUndoRedoSignals();
|
||||
this.slots.historyUpdated.emit();
|
||||
this.slots.historyUpdated.next();
|
||||
};
|
||||
|
||||
private readonly _initSubDoc = () => {
|
||||
@@ -65,7 +65,8 @@ export class DocImpl implements Doc {
|
||||
|
||||
private _loaded!: boolean;
|
||||
|
||||
private readonly _onLoadSlot = new Slot();
|
||||
// eslint-disable-next-line rxjs/finnish
|
||||
private readonly _onLoadSlot = new Subject();
|
||||
|
||||
/** Indicate whether the block tree is ready */
|
||||
private _ready = false;
|
||||
@@ -98,8 +99,10 @@ export class DocImpl implements Doc {
|
||||
readonly rootDoc: Y.Doc;
|
||||
|
||||
readonly slots = {
|
||||
historyUpdated: new Slot(),
|
||||
yBlockUpdated: new Slot<
|
||||
// eslint-disable-next-line rxjs/finnish
|
||||
historyUpdated: new Subject<void>(),
|
||||
// eslint-disable-next-line rxjs/finnish
|
||||
yBlockUpdated: new Subject<
|
||||
| {
|
||||
type: 'add';
|
||||
id: string;
|
||||
@@ -170,11 +173,11 @@ export class DocImpl implements Doc {
|
||||
}
|
||||
|
||||
private _handleYBlockAdd(id: string) {
|
||||
this.slots.yBlockUpdated.emit({ type: 'add', id });
|
||||
this.slots.yBlockUpdated.next({ type: 'add', id });
|
||||
}
|
||||
|
||||
private _handleYBlockDelete(id: string) {
|
||||
this.slots.yBlockUpdated.emit({ type: 'delete', id });
|
||||
this.slots.yBlockUpdated.next({ type: 'delete', id });
|
||||
}
|
||||
|
||||
private _handleYEvent(event: Y.YEvent<YBlock | Y.Text | Y.Array<unknown>>) {
|
||||
@@ -229,13 +232,13 @@ export class DocImpl implements Doc {
|
||||
private _destroy() {
|
||||
this.awarenessStore.destroy();
|
||||
this._ySpaceDoc.destroy();
|
||||
this._onLoadSlot.dispose();
|
||||
this._onLoadSlot.unsubscribe();
|
||||
this._loaded = false;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._destroy();
|
||||
this.slots.historyUpdated.dispose();
|
||||
this.slots.historyUpdated.unsubscribe();
|
||||
|
||||
if (this.ready) {
|
||||
this._yBlocks.unobserveDeep(this._handleYEvents);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Slot } from '@blocksuite/affine/global/slot';
|
||||
import {
|
||||
createYProxy,
|
||||
type DocMeta,
|
||||
type DocsPropertiesMeta,
|
||||
type WorkspaceMeta,
|
||||
} from '@blocksuite/affine/store';
|
||||
import { Subject } from 'rxjs';
|
||||
import type * as Y from 'yjs';
|
||||
|
||||
type MetaState = {
|
||||
@@ -15,10 +15,12 @@ type MetaState = {
|
||||
};
|
||||
|
||||
export class WorkspaceMetaImpl implements WorkspaceMeta {
|
||||
commonFieldsUpdated = new Slot();
|
||||
docMetaAdded = new Slot<string>();
|
||||
docMetaRemoved = new Slot<string>();
|
||||
docMetaUpdated = new Slot();
|
||||
/* eslint-disable rxjs/finnish */
|
||||
commonFieldsUpdated = new Subject<void>();
|
||||
docMetaAdded = new Subject<string>();
|
||||
docMetaRemoved = new Subject<string>();
|
||||
docMetaUpdated = new Subject<void>();
|
||||
/* eslint-enable rxjs/finnish */
|
||||
|
||||
private readonly _handleDocCollectionMetaEvents = (
|
||||
events: Y.YEvent<Y.Array<unknown> | Y.Text | Y.Map<unknown>>[]
|
||||
@@ -81,7 +83,7 @@ export class WorkspaceMetaImpl implements WorkspaceMeta {
|
||||
|
||||
setProperties(meta: DocsPropertiesMeta) {
|
||||
this._proxy.properties = meta;
|
||||
this.docMetaUpdated.emit();
|
||||
this.docMetaUpdated.next();
|
||||
}
|
||||
|
||||
get docMetas() {
|
||||
@@ -108,7 +110,7 @@ export class WorkspaceMetaImpl implements WorkspaceMeta {
|
||||
}
|
||||
|
||||
private _handleCommonFieldsEvent() {
|
||||
this.commonFieldsUpdated.emit();
|
||||
this.commonFieldsUpdated.next();
|
||||
}
|
||||
|
||||
private _handleDocMetaEvent() {
|
||||
@@ -118,7 +120,7 @@ export class WorkspaceMetaImpl implements WorkspaceMeta {
|
||||
|
||||
docMetas.forEach(docMeta => {
|
||||
if (!_prevDocs.has(docMeta.id)) {
|
||||
this.docMetaAdded.emit(docMeta.id);
|
||||
this.docMetaAdded.next(docMeta.id);
|
||||
}
|
||||
newDocs.add(docMeta.id);
|
||||
});
|
||||
@@ -126,13 +128,13 @@ export class WorkspaceMetaImpl implements WorkspaceMeta {
|
||||
_prevDocs.forEach(prevDocId => {
|
||||
const isRemoved = newDocs.has(prevDocId) === false;
|
||||
if (isRemoved) {
|
||||
this.docMetaRemoved.emit(prevDocId);
|
||||
this.docMetaRemoved.next(prevDocId);
|
||||
}
|
||||
});
|
||||
|
||||
this._prevDocs = newDocs;
|
||||
|
||||
this.docMetaUpdated.emit();
|
||||
this.docMetaUpdated.next();
|
||||
}
|
||||
|
||||
addDocMeta(doc: DocMeta, index?: number) {
|
||||
|
||||
@@ -2,7 +2,6 @@ import {
|
||||
BlockSuiteError,
|
||||
ErrorCode,
|
||||
} from '@blocksuite/affine/global/exceptions';
|
||||
import { Slot } from '@blocksuite/affine/global/slot';
|
||||
import { NoopLogger } from '@blocksuite/affine/global/utils';
|
||||
import {
|
||||
type CreateBlocksOptions,
|
||||
@@ -19,6 +18,7 @@ import {
|
||||
type BlobSource,
|
||||
MemoryBlobSource,
|
||||
} from '@blocksuite/affine/sync';
|
||||
import { Subject } from 'rxjs';
|
||||
import type { Awareness } from 'y-protocols/awareness.js';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
@@ -46,9 +46,11 @@ export class WorkspaceImpl implements Workspace {
|
||||
meta: WorkspaceMeta;
|
||||
|
||||
slots = {
|
||||
docListUpdated: new Slot(),
|
||||
docRemoved: new Slot<string>(),
|
||||
docCreated: new Slot<string>(),
|
||||
/* eslint-disable rxjs/finnish */
|
||||
docListUpdated: new Subject<void>(),
|
||||
docRemoved: new Subject<string>(),
|
||||
docCreated: new Subject<string>(),
|
||||
/* eslint-enable rxjs/finnish */
|
||||
};
|
||||
|
||||
get docs() {
|
||||
@@ -82,7 +84,7 @@ export class WorkspaceImpl implements Workspace {
|
||||
}
|
||||
|
||||
private _bindDocMetaEvents() {
|
||||
this.meta.docMetaAdded.on(docId => {
|
||||
this.meta.docMetaAdded.subscribe(docId => {
|
||||
const doc = new DocImpl({
|
||||
id: docId,
|
||||
collection: this,
|
||||
@@ -91,14 +93,14 @@ export class WorkspaceImpl implements Workspace {
|
||||
this.blockCollections.set(doc.id, doc);
|
||||
});
|
||||
|
||||
this.meta.docMetaUpdated.on(() => this.slots.docListUpdated.emit());
|
||||
this.meta.docMetaUpdated.subscribe(() => this.slots.docListUpdated.next());
|
||||
|
||||
this.meta.docMetaRemoved.on(id => {
|
||||
this.meta.docMetaRemoved.subscribe(id => {
|
||||
const doc = this._getDoc(id);
|
||||
if (!doc) return;
|
||||
this.blockCollections.delete(id);
|
||||
doc.remove();
|
||||
this.slots.docRemoved.emit(id);
|
||||
this.slots.docRemoved.next(id);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -126,7 +128,7 @@ export class WorkspaceImpl implements Workspace {
|
||||
createDate: Date.now(),
|
||||
tags: [],
|
||||
});
|
||||
this.slots.docCreated.emit(docId);
|
||||
this.slots.docCreated.next(docId);
|
||||
return this.getDoc(docId, {
|
||||
id: docId,
|
||||
query,
|
||||
|
||||
Reference in New Issue
Block a user