Просмотр исходного кода

Setup sync from secondaryDoc to primaryDoc when accepting chunks

Yuki Takei 1 год назад
Родитель
Сommit
59f3f1036d

+ 31 - 1
packages/editor/src/client/services-internal/unified-merge-view/use-unified-merge-view.ts

@@ -5,7 +5,10 @@ import {
   originalDocChangeEffect,
   getOriginalDoc,
 } from '@codemirror/merge';
-import { ChangeSet } from '@codemirror/state';
+import {
+  ChangeSet, Transaction,
+} from '@codemirror/state';
+import { EditorView } from '@codemirror/view';
 import * as Y from 'yjs';
 
 import { deltaToChangeSpecs } from '../../../utils/delta-to-changespecs';
@@ -88,4 +91,31 @@ export const useUnifiedMergeView = (
     };
   }, [codeMirrorEditor, isEnabled, primaryDoc, secondaryDoc]);
 
+  // Setup sync from secondaryDoc to primaryDoc when accepting chunks
+  useEffect(() => {
+    if (!isEnabled || primaryDoc == null || secondaryDoc == null || codeMirrorEditor == null) {
+      return;
+    }
+
+    // EditorView.updateListener を使用
+    const extension = EditorView.updateListener.of((update) => {
+      // handle only when the transaction has `userEvent: 'accept'` annotation
+      // ref: https://github.com/codemirror/merge/blob/6.8.0/src/unified.ts#L220
+      const shouldSync = update.transactions.some((tr) => {
+        const userEventAnnotation = tr.annotation(Transaction.userEvent);
+        return userEventAnnotation === 'accept';
+      });
+
+      if (shouldSync) {
+        Y.applyUpdate(primaryDoc, Y.encodeStateAsUpdate(secondaryDoc));
+      }
+    });
+
+    const cleanup = codeMirrorEditor?.appendExtensions([extension]);
+
+    return () => {
+      cleanup?.();
+    };
+  }, [codeMirrorEditor, isEnabled, primaryDoc, secondaryDoc]);
+
 };