Explorar o código

feat: handle delete keys

Vincent Chan %!s(int64=2) %!d(string=hai) anos
pai
achega
4794203e74

+ 83 - 22
frontend/app_flowy/packages/flowy_editor/lib/src/service/internal_key_event_handlers/delete_text_handler.dart

@@ -2,14 +2,8 @@ import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 
 import 'package:flowy_editor/flowy_editor.dart';
-import 'package:flowy_editor/src/service/keyboard_service.dart';
-
-// Handle delete text.
-FlowyKeyEventHandler deleteTextHandler = (editorState, event) {
-  if (event.logicalKey != LogicalKeyboardKey.backspace) {
-    return KeyEventResult.ignored;
-  }
 
+KeyEventResult _handleBackspace(EditorState editorState, RawKeyEvent event) {
   final selection = editorState.service.selectionService.currentSelection.value;
   if (selection == null) {
     return KeyEventResult.ignored;
@@ -22,7 +16,7 @@ FlowyKeyEventHandler deleteTextHandler = (editorState, event) {
     return KeyEventResult.ignored;
   }
 
-  TransactionBuilder transactionBuilder = TransactionBuilder(editorState);
+  final transactionBuilder = TransactionBuilder(editorState);
   if (textNodes.length == 1) {
     final textNode = textNodes.first;
     final index = textNode.delta.prevRunePosition(selection.start.offset);
@@ -74,23 +68,90 @@ FlowyKeyEventHandler deleteTextHandler = (editorState, event) {
       }
     }
   } else {
-    final first = textNodes.first;
-    final last = textNodes.last;
-    var content = textNodes.last.toRawString();
-    content = content.substring(selection.end.offset, content.length);
-    // Merge the fist and the last text node content,
-    //  and delete the all nodes expect for the first.
-    transactionBuilder
-      ..deleteNodes(textNodes.sublist(1))
-      ..mergeText(
-        first,
-        last,
-        firstOffset: selection.start.offset,
-        secondOffset: selection.end.offset,
-      );
+    _deleteNodes(transactionBuilder, textNodes, selection);
+  }
+
+  transactionBuilder.commit();
+
+  return KeyEventResult.handled;
+}
+
+KeyEventResult _handleDelete(EditorState editorState, RawKeyEvent event) {
+  final selection = editorState.service.selectionService.currentSelection.value;
+  if (selection == null) {
+    return KeyEventResult.ignored;
+  }
+  final nodes = editorState.service.selectionService.currentSelectedNodes;
+  // make sure all nodes is [TextNode].
+  final textNodes = nodes.whereType<TextNode>().toList();
+  if (textNodes.length != nodes.length) {
+    return KeyEventResult.ignored;
+  }
+
+  final transactionBuilder = TransactionBuilder(editorState);
+  if (textNodes.length == 1) {
+    final textNode = textNodes.first;
+    if (selection.start.offset >= textNode.delta.length) {
+      debugPrint("merge next line");
+      final nextNode = textNode.next;
+      if (nextNode == null) {
+        return KeyEventResult.ignored;
+      }
+      if (nextNode is TextNode) {
+        transactionBuilder.mergeText(textNode, nextNode);
+      }
+      transactionBuilder.deleteNode(nextNode);
+    } else {
+      final index = textNode.delta.nextRunePosition(selection.start.offset);
+      if (selection.isCollapsed) {
+        transactionBuilder.deleteText(
+          textNode,
+          selection.start.offset,
+          index - selection.start.offset,
+        );
+      } else {
+        transactionBuilder.deleteText(
+          textNode,
+          selection.start.offset,
+          selection.end.offset - selection.start.offset,
+        );
+      }
+    }
+  } else {
+    _deleteNodes(transactionBuilder, textNodes, selection);
   }
 
   transactionBuilder.commit();
 
   return KeyEventResult.handled;
+}
+
+void _deleteNodes(TransactionBuilder transactionBuilder,
+    List<TextNode> textNodes, Selection selection) {
+  final first = textNodes.first;
+  final last = textNodes.last;
+  var content = textNodes.last.toRawString();
+  content = content.substring(selection.end.offset, content.length);
+  // Merge the fist and the last text node content,
+  //  and delete the all nodes expect for the first.
+  transactionBuilder
+    ..deleteNodes(textNodes.sublist(1))
+    ..mergeText(
+      first,
+      last,
+      firstOffset: selection.start.offset,
+      secondOffset: selection.end.offset,
+    );
+}
+
+// Handle delete text.
+FlowyKeyEventHandler deleteTextHandler = (editorState, event) {
+  if (event.logicalKey == LogicalKeyboardKey.backspace) {
+    return _handleBackspace(editorState, event);
+  }
+  if (event.logicalKey == LogicalKeyboardKey.delete) {
+    return _handleDelete(editorState, event);
+  }
+
+  return KeyEventResult.ignored;
 };