Skip to content

Commit c13df25

Browse files
committed
feat: add accepting and rejecting changes
1 parent df3d2be commit c13df25

File tree

2 files changed

+64
-9
lines changed

2 files changed

+64
-9
lines changed

examples/07-collaboration/01-partykit/App.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,19 @@ export default function App() {
3636
onClick={() => {
3737
editor.pauseYjsSync();
3838
}}>
39-
Pause
39+
Pause syncing
4040
</button>
4141
<button
4242
onClick={() => {
43-
editor.resumeYjsSync();
43+
editor.resumeYjsSync(true);
4444
}}>
45-
Play
45+
Play (accept changes)
46+
</button>
47+
<button
48+
onClick={() => {
49+
editor.resumeYjsSync(false);
50+
}}>
51+
Play (reject changes)
4652
</button>
4753
<BlockNoteView editor={editor} />
4854
</>

packages/core/src/editor/BlockNoteEditor.ts

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,44 @@ export class BlockNoteEditor<
943943
};
944944
}
945945

946+
/**
947+
* To find a fragment in another ydoc, we need to search for it.
948+
*/
949+
private findTypeInOtherYdoc<T extends Y.AbstractType<any>>(
950+
ytype: T,
951+
otherYdoc: Y.Doc
952+
): T {
953+
const ydoc = ytype.doc!;
954+
if (ytype._item === null) {
955+
/**
956+
* If is a root type, we need to find the root key in the original ydoc
957+
* and use it to get the type in the other ydoc.
958+
*/
959+
const rootKey = Array.from(ydoc.share.keys()).find(
960+
(key) => ydoc.share.get(key) === ytype
961+
);
962+
if (rootKey == null) {
963+
throw new Error("type does not exist in other ydoc");
964+
}
965+
return otherYdoc.get(rootKey, ytype.constructor as new () => T) as T;
966+
} else {
967+
/**
968+
* If it is a sub type, we use the item id to find the history type.
969+
*/
970+
const ytypeItem = ytype._item;
971+
const otherStructs =
972+
otherYdoc.store.clients.get(ytypeItem.id.client) ?? [];
973+
const itemIndex = Y.findIndexSS(otherStructs, ytypeItem.id.clock);
974+
const otherItem = otherStructs[itemIndex] as Y.Item;
975+
const otherContent = otherItem.content as Y.ContentType;
976+
return otherContent.type as T;
977+
}
978+
}
979+
980+
public get isRemoteSyncing() {
981+
return this.yjsState !== undefined;
982+
}
983+
946984
private yjsState:
947985
| {
948986
prevFragment: Y.XmlFragment;
@@ -951,15 +989,22 @@ export class BlockNoteEditor<
951989
| undefined;
952990

953991
public pauseYjsSync() {
992+
if (this.isRemoteSyncing) {
993+
return;
994+
}
995+
954996
const prevFragment = this.options.collaboration?.fragment;
955997

956998
if (!prevFragment) {
957999
throw new Error("No Yjs document found");
9581000
}
9591001

960-
const nextFragment = prevFragment.clone();
1002+
const update = Y.encodeStateAsUpdate(prevFragment.doc!);
1003+
9611004
const doc = new Y.Doc();
962-
doc.getMap().set("cpy", nextFragment);
1005+
Y.applyUpdate(doc, update);
1006+
1007+
const nextFragment = this.findTypeInOtherYdoc(prevFragment, doc);
9631008

9641009
this.yjsState = {
9651010
prevFragment,
@@ -971,17 +1016,21 @@ export class BlockNoteEditor<
9711016
this._tiptapEditor.registerPlugin(ySyncPlugin(nextFragment));
9721017
}
9731018

974-
public resumeYjsSync() {
1019+
public resumeYjsSync(mergeChanges = false) {
9751020
if (!this.yjsState) {
9761021
throw new Error("No Yjs document found");
9771022
}
9781023
this._tiptapEditor.unregisterPlugin(ySyncPluginKey);
979-
this._tiptapEditor.registerPlugin(
980-
new SyncPlugin(this.yjsState.prevFragment).plugin
981-
);
1024+
const fragment = this.yjsState.prevFragment;
1025+
if (mergeChanges) {
1026+
const update = Y.encodeStateAsUpdate(this.yjsState.nextFragment.doc!);
1027+
Y.applyUpdate(fragment.doc!, update);
1028+
}
1029+
this._tiptapEditor.registerPlugin(new SyncPlugin(fragment).plugin);
9821030
this.cursorPlugin = new CursorPlugin(this.options.collaboration!);
9831031
this._tiptapEditor.registerPlugin(this.cursorPlugin.plugin);
9841032
this._tiptapEditor.registerPlugin(new UndoPlugin().plugin);
1033+
this.yjsState = undefined;
9851034
}
9861035

9871036
/**

0 commit comments

Comments
 (0)