|
|
@@ -6,6 +6,7 @@ import { GlobalCodeMirrorEditorKey } from '@growi/editor';
|
|
|
import { acceptChange, rejectChange } from '@growi/editor/dist/client/services/unified-merge-view';
|
|
|
import { useCodeMirrorEditorIsolated } from '@growi/editor/dist/client/stores/codemirror-editor';
|
|
|
import { useSecondaryYdocs } from '@growi/editor/dist/client/stores/use-secondary-ydocs';
|
|
|
+import { type Text as YText } from 'yjs';
|
|
|
|
|
|
import {
|
|
|
SseMessageSchema,
|
|
|
@@ -40,8 +41,58 @@ type DetectedDiff = Array<{
|
|
|
id: string,
|
|
|
}>
|
|
|
|
|
|
+const insertTextAtLine = (ytext: YText, lineNumber: number, textToInsert: string): void => {
|
|
|
+ // Get the entire text content
|
|
|
+ const content = ytext.toString();
|
|
|
+
|
|
|
+ // Split by newlines to get all lines
|
|
|
+ const lines = content.split('\n');
|
|
|
+
|
|
|
+ // Calculate the index position for insertion
|
|
|
+ let insertPosition = 0;
|
|
|
+
|
|
|
+ // Sum the length of all lines before the target line (plus newline characters)
|
|
|
+ for (let i = 0; i < lineNumber && i < lines.length; i++) {
|
|
|
+ insertPosition += lines[i].length + 1; // +1 for the newline character
|
|
|
+ }
|
|
|
+
|
|
|
+ // Insert the text at the calculated position
|
|
|
+ ytext.insert(insertPosition, textToInsert);
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+const getLineInfo = (ytext: YText, lineNumber: number): { text: string, startIndex: number } | null => {
|
|
|
+ // Get the entire text content
|
|
|
+ const content = ytext.toString();
|
|
|
+
|
|
|
+ // Split by newlines to get all lines
|
|
|
+ const lines = content.split('\n');
|
|
|
+
|
|
|
+ // Check if the requested line exists
|
|
|
+ if (lineNumber < 0 || lineNumber >= lines.length) {
|
|
|
+ return null; // Line doesn't exist
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the text of the specified line
|
|
|
+ const text = lines[lineNumber];
|
|
|
+
|
|
|
+ // Calculate the start index of the line
|
|
|
+ let startIndex = 0;
|
|
|
+ for (let i = 0; i < lineNumber; i++) {
|
|
|
+ startIndex += lines[i].length + 1; // +1 for the newline character
|
|
|
+ }
|
|
|
+
|
|
|
+ // Return comprehensive line information
|
|
|
+ return {
|
|
|
+ text,
|
|
|
+ startIndex,
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
export const useEditorAssistant = (): {postMessage: PostMessage, processMessage: ProcessMessage, accept: () => void, reject: () => void } => {
|
|
|
- const positionRef = useRef<number>(0);
|
|
|
+ // const positionRef = useRef<number>(0);
|
|
|
+ const lineRef = useRef<number>(0);
|
|
|
|
|
|
const [detectedDiff, setDetectedDiff] = useState<DetectedDiff>();
|
|
|
|
|
|
@@ -121,7 +172,13 @@ export const useEditorAssistant = (): {postMessage: PostMessage, processMessage:
|
|
|
ydocs.secondaryDoc.transact(() => {
|
|
|
pendingDetectedDiff.forEach((detectedDiff) => {
|
|
|
if (isReplaceDiff(detectedDiff.data)) {
|
|
|
- // TODO: https://redmine.weseek.co.jp/issues/164330
|
|
|
+ const lineInfo = getLineInfo(ytext, lineRef.current);
|
|
|
+ if (lineInfo != null && lineInfo.text !== detectedDiff.data.diff.replace) {
|
|
|
+ ytext.delete(lineInfo.startIndex, lineInfo.text.length);
|
|
|
+ insertTextAtLine(ytext, lineRef.current, detectedDiff.data.diff.replace);
|
|
|
+ }
|
|
|
+
|
|
|
+ lineRef.current += 1;
|
|
|
}
|
|
|
// if (isInsertDiff(detectedDiff.data)) {
|
|
|
// ytext.insert(positionRef.current, detectedDiff.data.diff.insert);
|
|
|
@@ -149,7 +206,8 @@ export const useEditorAssistant = (): {postMessage: PostMessage, processMessage:
|
|
|
// Set detectedDiff to undefined after applying all detectedDiff to secondaryDoc
|
|
|
if (detectedDiff?.filter(detectedDiff => detectedDiff.applied === false).length === 0) {
|
|
|
setDetectedDiff(undefined);
|
|
|
- positionRef.current = 0;
|
|
|
+ lineRef.current = 0;
|
|
|
+ // positionRef.current = 0;
|
|
|
}
|
|
|
}
|
|
|
}, [codeMirrorEditor, detectedDiff, ydocs?.secondaryDoc]);
|