mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-20 03:26:47 +08:00
refactor(editor): history as a store extension (#12214)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Refactor** - Improved history and undo/redo management across the app by introducing a dedicated history extension. Undo/redo operations now use a more focused undo manager, resulting in clearer and more consistent behavior. - **Documentation** - Updated API documentation to reflect changes in history management, including revised method signatures and removal of outdated event references. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import { signal } from '@preact/signals-core';
|
||||
import { Subject } from 'rxjs';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import type { Store } from '../../model';
|
||||
import { StoreExtension } from '../store-extension';
|
||||
|
||||
export class HistoryExtension extends StoreExtension {
|
||||
static override readonly key = 'history';
|
||||
|
||||
private readonly _history!: Y.UndoManager;
|
||||
|
||||
private readonly _canRedo = signal(false);
|
||||
|
||||
private readonly _canUndo = signal(false);
|
||||
|
||||
readonly onUpdated = new Subject<void>();
|
||||
|
||||
constructor(store: Store) {
|
||||
super(store);
|
||||
|
||||
this._history = new Y.UndoManager([this.store.doc.yBlocks], {
|
||||
trackedOrigins: new Set([this.store.doc.spaceDoc.clientID]),
|
||||
});
|
||||
}
|
||||
|
||||
private readonly _updateCanUndoRedoSignals = () => {
|
||||
const canRedo = this._history.canRedo();
|
||||
const canUndo = this._history.canUndo();
|
||||
if (this._canRedo.peek() !== canRedo) {
|
||||
this._canRedo.value = canRedo;
|
||||
}
|
||||
if (this._canUndo.peek() !== canUndo) {
|
||||
this._canUndo.value = canUndo;
|
||||
}
|
||||
};
|
||||
|
||||
get canRedo() {
|
||||
return this._canRedo.peek();
|
||||
}
|
||||
|
||||
get canUndo() {
|
||||
return this._canUndo.peek();
|
||||
}
|
||||
|
||||
get canRedo$() {
|
||||
return this._canRedo;
|
||||
}
|
||||
|
||||
get canUndo$() {
|
||||
return this._canUndo;
|
||||
}
|
||||
|
||||
get undoManager() {
|
||||
return this._history;
|
||||
}
|
||||
|
||||
override loaded() {
|
||||
this._updateCanUndoRedoSignals();
|
||||
this._history.on('stack-cleared', this._historyObserver);
|
||||
this._history.on('stack-item-added', this._historyObserver);
|
||||
this._history.on('stack-item-popped', this._historyObserver);
|
||||
this._history.on('stack-item-updated', this._historyObserver);
|
||||
}
|
||||
|
||||
private readonly _historyObserver = () => {
|
||||
this._updateCanUndoRedoSignals();
|
||||
this.onUpdated.next();
|
||||
};
|
||||
|
||||
override disposed() {
|
||||
super.disposed();
|
||||
this._history.off('stack-cleared', this._historyObserver);
|
||||
this._history.off('stack-item-added', this._historyObserver);
|
||||
this._history.off('stack-item-popped', this._historyObserver);
|
||||
this._history.off('stack-item-updated', this._historyObserver);
|
||||
this.onUpdated.complete();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './history-extension';
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './extension';
|
||||
export * from './history';
|
||||
export * from './schema';
|
||||
export * from './selection';
|
||||
export * from './store-extension';
|
||||
|
||||
@@ -94,8 +94,14 @@ export class StoreSelectionExtension extends StoreExtension {
|
||||
}
|
||||
);
|
||||
|
||||
this.store.history.on('stack-item-added', this._itemAdded);
|
||||
this.store.history.on('stack-item-popped', this._itemPopped);
|
||||
this.store.history.undoManager.on('stack-item-added', this._itemAdded);
|
||||
this.store.history.undoManager.on('stack-item-popped', this._itemPopped);
|
||||
}
|
||||
|
||||
override disposed() {
|
||||
super.disposed();
|
||||
this.store.history.undoManager.off('stack-item-added', this._itemAdded);
|
||||
this.store.history.undoManager.off('stack-item-popped', this._itemPopped);
|
||||
}
|
||||
|
||||
get value() {
|
||||
|
||||
Reference in New Issue
Block a user