From 73cfe39e41fc67b89cfc205024ccf82ce30efcfe Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Tue, 6 Sep 2022 10:55:29 +0800 Subject: [PATCH] feat: refactor copy / paste / redo / undo / select all / format event handler --- .../copy_paste_handler.dart | 29 +++---- .../format_style_handler.dart | 75 ++++++++++++++++ .../redo_undo_handler.dart | 19 ++-- .../select_all_handler.dart | 21 ++--- ...pdate_text_style_by_command_x_handler.dart | 48 ----------- .../built_in_shortcut_events.dart | 86 +++++++++++++++---- 6 files changed, 172 insertions(+), 106 deletions(-) create mode 100644 frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/format_style_handler.dart delete mode 100644 frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/update_text_style_by_command_x_handler.dart diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart index 6a4f58fa86..15a7081653 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart @@ -1,9 +1,7 @@ import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/src/infra/html_converter.dart'; import 'package:appflowy_editor/src/document/node_iterator.dart'; -import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:rich_clipboard/rich_clipboard.dart'; _handleCopy(EditorState editorState) async { @@ -304,18 +302,17 @@ _deleteSelectedContent(EditorState editorState) { tb.commit(); } -ShortcutEventHandler copyPasteKeysHandler = (editorState, event) { - if (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyC) { - _handleCopy(editorState); - return KeyEventResult.handled; - } - if (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyV) { - _handlePaste(editorState); - return KeyEventResult.handled; - } - if (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyX) { - _handleCut(editorState); - return KeyEventResult.handled; - } - return KeyEventResult.ignored; +ShortcutEventHandler copyEventHandler = (editorState, event) { + _handleCopy(editorState); + return KeyEventResult.handled; +}; + +ShortcutEventHandler pasteEventHandler = (editorState, event) { + _handlePaste(editorState); + return KeyEventResult.handled; +}; + +ShortcutEventHandler cutEventHandler = (editorState, event) { + _handleCut(editorState); + return KeyEventResult.handled; }; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/format_style_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/format_style_handler.dart new file mode 100644 index 0000000000..2f17296ca6 --- /dev/null +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/format_style_handler.dart @@ -0,0 +1,75 @@ +import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart'; +import 'package:flutter/material.dart'; + +import 'package:appflowy_editor/src/document/node.dart'; +import 'package:appflowy_editor/src/service/default_text_operations/format_rich_text_style.dart'; + +ShortcutEventHandler formatBoldEventHandler = (editorState, event) { + final selection = editorState.service.selectionService.currentSelection.value; + final nodes = editorState.service.selectionService.currentSelectedNodes; + final textNodes = nodes.whereType().toList(growable: false); + if (selection == null || textNodes.isEmpty) { + return KeyEventResult.ignored; + } + formatBold(editorState); + return KeyEventResult.handled; +}; + +ShortcutEventHandler formatItalicEventHandler = (editorState, event) { + final selection = editorState.service.selectionService.currentSelection.value; + final nodes = editorState.service.selectionService.currentSelectedNodes; + final textNodes = nodes.whereType().toList(growable: false); + if (selection == null || textNodes.isEmpty) { + return KeyEventResult.ignored; + } + formatItalic(editorState); + return KeyEventResult.handled; +}; + +ShortcutEventHandler formatUnderlineEventHandler = (editorState, event) { + final selection = editorState.service.selectionService.currentSelection.value; + final nodes = editorState.service.selectionService.currentSelectedNodes; + final textNodes = nodes.whereType().toList(growable: false); + if (selection == null || textNodes.isEmpty) { + return KeyEventResult.ignored; + } + formatUnderline(editorState); + return KeyEventResult.handled; +}; + +ShortcutEventHandler formatStrikethroughEventHandler = (editorState, event) { + final selection = editorState.service.selectionService.currentSelection.value; + final nodes = editorState.service.selectionService.currentSelectedNodes; + final textNodes = nodes.whereType().toList(growable: false); + if (selection == null || textNodes.isEmpty) { + return KeyEventResult.ignored; + } + formatStrikethrough(editorState); + return KeyEventResult.handled; +}; + +ShortcutEventHandler formatHighlightEventHandler = (editorState, event) { + final selection = editorState.service.selectionService.currentSelection.value; + final nodes = editorState.service.selectionService.currentSelectedNodes; + final textNodes = nodes.whereType().toList(growable: false); + if (selection == null || textNodes.isEmpty) { + return KeyEventResult.ignored; + } + formatHighlight(editorState); + return KeyEventResult.handled; +}; + +ShortcutEventHandler formatLinkEventHandler = (editorState, event) { + final selection = editorState.service.selectionService.currentSelection.value; + final nodes = editorState.service.selectionService.currentSelectedNodes; + final textNodes = nodes.whereType().toList(growable: false); + if (selection == null || textNodes.isEmpty) { + return KeyEventResult.ignored; + } + if (editorState.service.toolbarService + ?.triggerHandler('appflowy.toolbar.link') == + true) { + return KeyEventResult.handled; + } + return KeyEventResult.ignored; +}; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/redo_undo_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/redo_undo_handler.dart index 7bec895f91..e20d6dc43d 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/redo_undo_handler.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/redo_undo_handler.dart @@ -1,15 +1,12 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart'; -ShortcutEventHandler redoUndoKeysHandler = (editorState, event) { - if (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyZ) { - if (event.isShiftPressed) { - editorState.undoManager.redo(); - } else { - editorState.undoManager.undo(); - } - return KeyEventResult.handled; - } - return KeyEventResult.ignored; +ShortcutEventHandler redoEventHandler = (editorState, event) { + editorState.undoManager.redo(); + return KeyEventResult.handled; +}; + +ShortcutEventHandler undoEventHandler = (editorState, event) { + editorState.undoManager.undo(); + return KeyEventResult.handled; }; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/select_all_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/select_all_handler.dart index 6f8e1ae750..9841ec3167 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/select_all_handler.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/select_all_handler.dart @@ -1,9 +1,10 @@ -import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:appflowy_editor/src/document/node.dart'; +import 'package:appflowy_editor/src/document/position.dart'; +import 'package:appflowy_editor/src/document/selection.dart'; import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -KeyEventResult _selectAll(EditorState editorState) { +ShortcutEventHandler selectAllHandler = (editorState, event) { if (editorState.document.root.children.isEmpty) { return KeyEventResult.handled; } @@ -13,15 +14,11 @@ KeyEventResult _selectAll(EditorState editorState) { if (lastNode is TextNode) { offset = lastNode.delta.length; } - editorState.updateCursorSelection(Selection( + editorState.updateCursorSelection( + Selection( start: Position(path: firstNode.path, offset: 0), - end: Position(path: lastNode.path, offset: offset))); + end: Position(path: lastNode.path, offset: offset), + ), + ); return KeyEventResult.handled; -} - -ShortcutEventHandler selectAllHandler = (editorState, event) { - if (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyA) { - return _selectAll(editorState); - } - return KeyEventResult.ignored; }; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/update_text_style_by_command_x_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/update_text_style_by_command_x_handler.dart deleted file mode 100644 index 19d50f80cf..0000000000 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/update_text_style_by_command_x_handler.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart'; -import 'package:flutter/material.dart'; - -import 'package:appflowy_editor/src/document/node.dart'; -import 'package:appflowy_editor/src/service/default_text_operations/format_rich_text_style.dart'; - -import 'package:flutter/services.dart'; - -ShortcutEventHandler updateTextStyleByCommandXHandler = (editorState, event) { - if (!event.isMetaPressed) { - return KeyEventResult.ignored; - } - - final selection = editorState.service.selectionService.currentSelection.value; - final nodes = editorState.service.selectionService.currentSelectedNodes; - final textNodes = nodes.whereType().toList(growable: false); - - if (selection == null || textNodes.isEmpty) { - return KeyEventResult.ignored; - } - - if (event.logicalKey == LogicalKeyboardKey.keyB) { - formatBold(editorState); - return KeyEventResult.handled; - } else if (event.logicalKey == LogicalKeyboardKey.keyI) { - formatItalic(editorState); - return KeyEventResult.handled; - } else if (event.logicalKey == LogicalKeyboardKey.keyU) { - formatUnderline(editorState); - return KeyEventResult.handled; - } else if (event.logicalKey == LogicalKeyboardKey.keyS && - event.isShiftPressed) { - formatStrikethrough(editorState); - return KeyEventResult.handled; - } else if (event.logicalKey == LogicalKeyboardKey.keyH && - event.isShiftPressed) { - formatHighlight(editorState); - return KeyEventResult.handled; - } else if (event.logicalKey == LogicalKeyboardKey.keyK) { - if (editorState.service.toolbarService - ?.triggerHandler('appflowy.toolbar.link') == - true) { - return KeyEventResult.handled; - } - } - - return KeyEventResult.ignored; -}; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart index 9f96ef3185..d313a33dc8 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart @@ -8,7 +8,7 @@ import 'package:appflowy_editor/src/service/internal_key_event_handlers/page_up_ import 'package:appflowy_editor/src/service/internal_key_event_handlers/redo_undo_handler.dart'; import 'package:appflowy_editor/src/service/internal_key_event_handlers/select_all_handler.dart'; import 'package:appflowy_editor/src/service/internal_key_event_handlers/slash_handler.dart'; -import 'package:appflowy_editor/src/service/internal_key_event_handlers/update_text_style_by_command_x_handler.dart'; +import 'package:appflowy_editor/src/service/internal_key_event_handlers/format_style_handler.dart'; import 'package:appflowy_editor/src/service/internal_key_event_handlers/whitespace_handler.dart'; import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event.dart'; @@ -102,6 +102,72 @@ List builtInShortcutEvents = [ windowsCommand: 'ctrl+shift+arrow right', handler: cursorEndSelect, ), + ShortcutEvent( + key: 'Redo', + command: 'meta+shift+z', + windowsCommand: 'ctrl+shift+z', + handler: redoEventHandler, + ), + ShortcutEvent( + key: 'Undo', + command: 'meta+z', + windowsCommand: 'ctrl+z', + handler: undoEventHandler, + ), + ShortcutEvent( + key: 'Format bold', + command: 'meta+b', + windowsCommand: 'ctrl+b', + handler: formatBoldEventHandler, + ), + ShortcutEvent( + key: 'Format italic', + command: 'meta+i', + windowsCommand: 'ctrl+i', + handler: formatItalicEventHandler, + ), + ShortcutEvent( + key: 'Format underline', + command: 'meta+u', + windowsCommand: 'ctrl+u', + handler: formatUnderlineEventHandler, + ), + ShortcutEvent( + key: 'Format strikethrough', + command: 'meta+shift+s', + windowsCommand: 'ctrl+shift+s', + handler: formatStrikethroughEventHandler, + ), + ShortcutEvent( + key: 'Format highlight', + command: 'meta+shift+h', + windowsCommand: 'ctrl+shift+h', + handler: formatHighlightEventHandler, + ), + ShortcutEvent( + key: 'Format link', + command: 'meta+k', + windowsCommand: 'ctrl+k', + handler: formatLinkEventHandler, + ), + ShortcutEvent( + key: 'Copy', + command: 'meta+c', + windowsCommand: 'ctrl+c', + handler: copyEventHandler, + ), + ShortcutEvent( + key: 'Paste', + command: 'meta+v', + windowsCommand: 'ctrl+v', + handler: pasteEventHandler, + ), + ShortcutEvent( + key: 'Paste', + command: 'meta+x', + windowsCommand: 'ctrl+x', + handler: cutEventHandler, + ), // TODO: split the keys. ShortcutEvent( key: 'Delete Text', @@ -113,29 +179,11 @@ List builtInShortcutEvents = [ command: 'slash', handler: slashShortcutHandler, ), - ShortcutEvent( - key: 'copy / paste', - command: 'meta+c,meta+v', - windowsCommand: 'ctrl+c,ctrl+v', - handler: copyPasteKeysHandler, - ), - ShortcutEvent( - key: 'redo / undo', - command: 'meta+z,meta+meta+shift+z', - windowsCommand: 'ctrl+z,meta+ctrl+shift+z', - handler: redoUndoKeysHandler, - ), ShortcutEvent( key: 'enter', command: 'enter', handler: enterWithoutShiftInTextNodesHandler, ), - ShortcutEvent( - key: 'update text style', - command: 'meta+b,meta+i,meta+u,meta+shift+s,meta+shift+h,meta+k', - windowsCommand: 'ctrl+b,ctrl+i,ctrl+u,ctrl+shift+s,ctrl+shift+h,ctrl+k', - handler: updateTextStyleByCommandXHandler, - ), ShortcutEvent( key: 'markdown', command: 'space',