Pārlūkot izejas kodu

fix: #1967 the summarize feature generates duplicate answers

Lucas.Xu 2 gadi atpakaļ
vecāks
revīzija
dd9c3dd2a3

+ 12 - 7
frontend/appflowy_flutter/packages/appflowy_editor/lib/src/core/transform/transaction.dart

@@ -355,7 +355,7 @@ extension TextTransaction on Transaction {
             texts.last,
           );
         } else {
-          if (i < texts.length) {
+          if (i < texts.length - 1) {
             replaceText(
               textNode,
               0,
@@ -367,6 +367,7 @@ extension TextTransaction on Transaction {
           }
         }
       }
+      afterSelection = null;
       return;
     }
 
@@ -389,21 +390,25 @@ extension TextTransaction on Transaction {
             text,
           );
         } else {
-          if (i < textNodes.length) {
+          if (i < textNodes.length - 1) {
             replaceText(
               textNodes[i],
               0,
               textNodes[i].toPlainText().length,
-              texts[i],
+              text,
             );
           } else {
-            insertNode(
-              textNodes.last.path,
-              TextNode(delta: Delta()..insert(text)),
-            );
+            var path = textNodes.first.path;
+            var j = i - textNodes.length + length - 1;
+            while (j > 0) {
+              path = path.next;
+              j--;
+            }
+            insertNode(path, TextNode(delta: Delta()..insert(text)));
           }
         }
       }
+      afterSelection = null;
       return;
     }
   }

+ 132 - 0
frontend/appflowy_flutter/packages/appflowy_editor/test/core/transform/transaction_test.dart

@@ -0,0 +1,132 @@
+import 'package:appflowy_editor/appflowy_editor.dart';
+import 'package:flutter_test/flutter_test.dart';
+import '../../infra/test_editor.dart';
+
+Document createEmptyDocument() {
+  return Document(
+    root: Node(
+      type: 'editor',
+    ),
+  );
+}
+
+void main() async {
+  group('transaction.dart', () {
+    testWidgets('test replaceTexts, textNodes.length == texts.length',
+        (tester) async {
+      TestWidgetsFlutterBinding.ensureInitialized();
+
+      final editor = tester.editor
+        ..insertTextNode('0123456789')
+        ..insertTextNode('0123456789')
+        ..insertTextNode('0123456789')
+        ..insertTextNode('0123456789');
+      await editor.startTesting();
+      await tester.pumpAndSettle();
+
+      expect(editor.documentLength, 4);
+
+      final selection = Selection(
+        start: Position(path: [0], offset: 4),
+        end: Position(path: [3], offset: 4),
+      );
+      final transaction = editor.editorState.transaction;
+      var textNodes = [0, 1, 2, 3]
+          .map((e) => editor.nodeAtPath([e])!)
+          .whereType<TextNode>()
+          .toList(growable: false);
+      final texts = ['ABC', 'ABC', 'ABC', 'ABC'];
+      transaction.replaceTexts(textNodes, selection, texts);
+      editor.editorState.apply(transaction);
+      await tester.pumpAndSettle();
+
+      expect(editor.documentLength, 4);
+      textNodes = [0, 1, 2, 3]
+          .map((e) => editor.nodeAtPath([e])!)
+          .whereType<TextNode>()
+          .toList(growable: false);
+      expect(textNodes[0].toPlainText(), '0123ABC');
+      expect(textNodes[1].toPlainText(), 'ABC');
+      expect(textNodes[2].toPlainText(), 'ABC');
+      expect(textNodes[3].toPlainText(), 'ABC456789');
+    });
+
+    testWidgets('test replaceTexts, textNodes.length >  texts.length',
+        (tester) async {
+      TestWidgetsFlutterBinding.ensureInitialized();
+
+      final editor = tester.editor
+        ..insertTextNode('0123456789')
+        ..insertTextNode('0123456789')
+        ..insertTextNode('0123456789')
+        ..insertTextNode('0123456789')
+        ..insertTextNode('0123456789');
+      await editor.startTesting();
+      await tester.pumpAndSettle();
+
+      expect(editor.documentLength, 5);
+
+      final selection = Selection(
+        start: Position(path: [0], offset: 4),
+        end: Position(path: [4], offset: 4),
+      );
+      final transaction = editor.editorState.transaction;
+      var textNodes = [0, 1, 2, 3, 4]
+          .map((e) => editor.nodeAtPath([e])!)
+          .whereType<TextNode>()
+          .toList(growable: false);
+      final texts = ['ABC', 'ABC', 'ABC', 'ABC'];
+      transaction.replaceTexts(textNodes, selection, texts);
+      editor.editorState.apply(transaction);
+      await tester.pumpAndSettle();
+
+      expect(editor.documentLength, 4);
+      textNodes = [0, 1, 2, 3]
+          .map((e) => editor.nodeAtPath([e])!)
+          .whereType<TextNode>()
+          .toList(growable: false);
+      expect(textNodes[0].toPlainText(), '0123ABC');
+      expect(textNodes[1].toPlainText(), 'ABC');
+      expect(textNodes[2].toPlainText(), 'ABC');
+      expect(textNodes[3].toPlainText(), 'ABC456789');
+    });
+
+    testWidgets('test replaceTexts, textNodes.length < texts.length',
+        (tester) async {
+      TestWidgetsFlutterBinding.ensureInitialized();
+
+      final editor = tester.editor
+        ..insertTextNode('0123456789')
+        ..insertTextNode('0123456789')
+        ..insertTextNode('0123456789');
+      await editor.startTesting();
+      await tester.pumpAndSettle();
+
+      expect(editor.documentLength, 3);
+
+      final selection = Selection(
+        start: Position(path: [0], offset: 4),
+        end: Position(path: [2], offset: 4),
+      );
+      final transaction = editor.editorState.transaction;
+      var textNodes = [0, 1, 2]
+          .map((e) => editor.nodeAtPath([e])!)
+          .whereType<TextNode>()
+          .toList(growable: false);
+      final texts = ['ABC', 'ABC', 'ABC', 'ABC'];
+      transaction.replaceTexts(textNodes, selection, texts);
+      editor.editorState.apply(transaction);
+      await tester.pumpAndSettle();
+
+      expect(editor.documentLength, 4);
+      textNodes = [0, 1, 2, 3]
+          .map((e) => editor.nodeAtPath([e])!)
+          .whereType<TextNode>()
+          .toList(growable: false);
+      expect(textNodes[0].toPlainText(), '0123ABC');
+      expect(textNodes[1].toPlainText(), 'ABC');
+      expect(textNodes[2].toPlainText(), 'ABC');
+      expect(textNodes[3].toPlainText(), 'ABC456789');
+    });
+  });
+}