Преглед изворни кода

fix: select all in code block handler (#2538)

* fix: select all in code block handler

Closes: #2320

* fix: do not force unwrap in toDocument

* fix: refactor unwrapping and selection
Mathias Mogensen пре 2 година
родитељ
комит
f8d09e4894

+ 14 - 6
frontend/appflowy_flutter/lib/plugins/document/application/document_data_pb_extension.dart

@@ -4,28 +4,36 @@ import 'package:appflowy_backend/log.dart';
 import 'package:appflowy_backend/protobuf/flowy-document2/protobuf.dart';
 import 'package:appflowy_editor/appflowy_editor.dart'
     show Document, Node, Attributes, Delta, ParagraphBlockKeys;
+import 'package:collection/collection.dart';
 
 extension AppFlowyEditor on DocumentDataPB2 {
   Document? toDocument() {
     final rootId = pageId;
     try {
       final root = buildNode(rootId);
-      return Document(root: root);
+
+      if (root != null) {
+        return Document(root: root);
+      }
+
+      return null;
     } catch (e) {
       Log.error('create document error: $e');
       return null;
     }
   }
 
-  Node buildNode(String id) {
-    final block = blocks[id]!; // TODO: don't use force unwrap
-    final childrenId = block.childrenId;
+  Node? buildNode(String id) {
+    final block = blocks[id];
+    final childrenId = block?.childrenId;
     final childrenIds = meta.childrenMap[childrenId]?.children;
+
     final children = <Node>[];
     if (childrenIds != null && childrenIds.isNotEmpty) {
-      children.addAll(childrenIds.map((e) => buildNode(e)));
+      children.addAll(childrenIds.map((e) => buildNode(e)).whereNotNull());
     }
-    return block.toNode(children: children);
+
+    return block?.toNode(children: children);
   }
 }
 

+ 37 - 0
frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/code_block/code_block_shortcut_event.dart

@@ -11,6 +11,7 @@ final List<CommandShortcutEvent> codeBlockCommands = [
   insertNewParagraphNextToCodeBlockCommand,
   tabToInsertSpacesInCodeBlockCommand,
   tabToDeleteSpacesInCodeBlockCommand,
+  selectAllInCodeBlockCommand,
 ];
 
 /// press the enter key in code block to insert a new line in it.
@@ -84,6 +85,18 @@ final CommandShortcutEvent tabToDeleteSpacesInCodeBlockCommand =
   handler: _tabToDeleteSpacesInCodeBlockCommandHandler,
 );
 
+/// CTRL+A to select all content inside a Code Block, if cursor is inside one.
+///
+/// - support
+///   - desktop
+///   - web
+final CommandShortcutEvent selectAllInCodeBlockCommand = CommandShortcutEvent(
+  key: 'ctrl + a to select all content inside a code block',
+  command: 'ctrl+a',
+  macOSCommand: 'meta+a',
+  handler: _selectAllInCodeBlockCommandHandler,
+);
+
 CharacterShortcutEventHandler _enterInCodeBlockCommandHandler =
     (editorState) async {
   final selection = editorState.selection;
@@ -227,3 +240,27 @@ CommandShortcutEventHandler _tabToDeleteSpacesInCodeBlockCommandHandler =
   }
   return KeyEventResult.handled;
 };
+
+CommandShortcutEventHandler _selectAllInCodeBlockCommandHandler =
+    (editorState) {
+  final selection = editorState.selection;
+  if (selection == null || !selection.isSingle) {
+    return KeyEventResult.ignored;
+  }
+
+  final node = editorState.getNodeAtPath(selection.end.path);
+  final delta = node?.delta;
+  if (node == null || delta == null || node.type != CodeBlockKeys.type) {
+    return KeyEventResult.ignored;
+  }
+
+  editorState.service.selectionService.updateSelection(
+    Selection.single(
+      path: node.path,
+      startOffset: 0,
+      endOffset: delta.length,
+    ),
+  );
+
+  return KeyEventResult.handled;
+};