فهرست منبع

fix: emoji position

Vincent Chan 2 سال پیش
والد
کامیت
c554720dff

+ 26 - 1
frontend/app_flowy/packages/flowy_editor/lib/src/document/text_delta.dart

@@ -475,10 +475,35 @@ class Delta extends Iterable<TextOperation> {
     return _operations.map((e) => e.toJson()).toList();
   }
 
-  String toRawString() {
+  int prevRunePosition(int pos) {
+    if (pos == 0) {
+      return pos;
+    }
     _rawString ??=
         _operations.whereType<TextInsert>().map((op) => op.content).join();
     _runeIndexes ??= stringIndexes(_rawString!);
+    return _runeIndexes![pos - 1];
+  }
+
+  int nextRunePosition(int pos) {
+    final stringContent = toRawString();
+    if (pos >= stringContent.length - 1) {
+      return stringContent.length;
+    }
+    _runeIndexes ??= stringIndexes(_rawString!);
+
+    for (var i = pos + 1; i < _runeIndexes!.length; i++) {
+      if (_runeIndexes![i] != pos) {
+        return _runeIndexes![i];
+      }
+    }
+
+    return pos;
+  }
+
+  String toRawString() {
+    _rawString ??=
+        _operations.whereType<TextInsert>().map((op) => op.content).join();
     return _rawString!;
   }
 

+ 11 - 3
frontend/app_flowy/packages/flowy_editor/lib/src/service/internal_key_event_handlers/arrow_keys_handler.dart

@@ -12,8 +12,8 @@ int _endOffsetOfNode(Node node) {
 
 extension on Position {
   Position? goLeft(EditorState editorState) {
+    final node = editorState.document.nodeAtPath(path)!;
     if (offset == 0) {
-      final node = editorState.document.nodeAtPath(path)!;
       final prevNode = node.previous;
       if (prevNode != null) {
         return Position(
@@ -22,7 +22,11 @@ extension on Position {
       return null;
     }
 
-    return Position(path: path, offset: offset - 1);
+    if (node is TextNode) {
+      return Position(path: path, offset: node.delta.prevRunePosition(offset));
+    } else {
+      return Position(path: path, offset: offset);
+    }
   }
 
   Position? goRight(EditorState editorState) {
@@ -36,7 +40,11 @@ extension on Position {
       return null;
     }
 
-    return Position(path: path, offset: offset + 1);
+    if (node is TextNode) {
+      return Position(path: path, offset: node.delta.nextRunePosition(offset));
+    } else {
+      return Position(path: path, offset: offset);
+    }
   }
 }