mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: refactor copy / paste / redo / undo / select all / format event handler
This commit is contained in:
parent
804b2b27c1
commit
73cfe39e41
@ -1,9 +1,7 @@
|
|||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:appflowy_editor/src/infra/html_converter.dart';
|
import 'package:appflowy_editor/src/infra/html_converter.dart';
|
||||||
import 'package:appflowy_editor/src/document/node_iterator.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/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:rich_clipboard/rich_clipboard.dart';
|
import 'package:rich_clipboard/rich_clipboard.dart';
|
||||||
|
|
||||||
_handleCopy(EditorState editorState) async {
|
_handleCopy(EditorState editorState) async {
|
||||||
@ -304,18 +302,17 @@ _deleteSelectedContent(EditorState editorState) {
|
|||||||
tb.commit();
|
tb.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
ShortcutEventHandler copyPasteKeysHandler = (editorState, event) {
|
ShortcutEventHandler copyEventHandler = (editorState, event) {
|
||||||
if (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyC) {
|
_handleCopy(editorState);
|
||||||
_handleCopy(editorState);
|
return KeyEventResult.handled;
|
||||||
return KeyEventResult.handled;
|
};
|
||||||
}
|
|
||||||
if (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyV) {
|
ShortcutEventHandler pasteEventHandler = (editorState, event) {
|
||||||
_handlePaste(editorState);
|
_handlePaste(editorState);
|
||||||
return KeyEventResult.handled;
|
return KeyEventResult.handled;
|
||||||
}
|
};
|
||||||
if (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyX) {
|
|
||||||
_handleCut(editorState);
|
ShortcutEventHandler cutEventHandler = (editorState, event) {
|
||||||
return KeyEventResult.handled;
|
_handleCut(editorState);
|
||||||
}
|
return KeyEventResult.handled;
|
||||||
return KeyEventResult.ignored;
|
|
||||||
};
|
};
|
||||||
|
@ -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<TextNode>().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<TextNode>().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<TextNode>().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<TextNode>().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<TextNode>().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<TextNode>().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;
|
||||||
|
};
|
@ -1,15 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart';
|
import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart';
|
||||||
|
|
||||||
ShortcutEventHandler redoUndoKeysHandler = (editorState, event) {
|
ShortcutEventHandler redoEventHandler = (editorState, event) {
|
||||||
if (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyZ) {
|
editorState.undoManager.redo();
|
||||||
if (event.isShiftPressed) {
|
return KeyEventResult.handled;
|
||||||
editorState.undoManager.redo();
|
};
|
||||||
} else {
|
|
||||||
editorState.undoManager.undo();
|
ShortcutEventHandler undoEventHandler = (editorState, event) {
|
||||||
}
|
editorState.undoManager.undo();
|
||||||
return KeyEventResult.handled;
|
return KeyEventResult.handled;
|
||||||
}
|
|
||||||
return KeyEventResult.ignored;
|
|
||||||
};
|
};
|
||||||
|
@ -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:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart';
|
||||||
import 'package:flutter/material.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) {
|
if (editorState.document.root.children.isEmpty) {
|
||||||
return KeyEventResult.handled;
|
return KeyEventResult.handled;
|
||||||
}
|
}
|
||||||
@ -13,15 +14,11 @@ KeyEventResult _selectAll(EditorState editorState) {
|
|||||||
if (lastNode is TextNode) {
|
if (lastNode is TextNode) {
|
||||||
offset = lastNode.delta.length;
|
offset = lastNode.delta.length;
|
||||||
}
|
}
|
||||||
editorState.updateCursorSelection(Selection(
|
editorState.updateCursorSelection(
|
||||||
|
Selection(
|
||||||
start: Position(path: firstNode.path, offset: 0),
|
start: Position(path: firstNode.path, offset: 0),
|
||||||
end: Position(path: lastNode.path, offset: offset)));
|
end: Position(path: lastNode.path, offset: offset),
|
||||||
|
),
|
||||||
|
);
|
||||||
return KeyEventResult.handled;
|
return KeyEventResult.handled;
|
||||||
}
|
|
||||||
|
|
||||||
ShortcutEventHandler selectAllHandler = (editorState, event) {
|
|
||||||
if (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyA) {
|
|
||||||
return _selectAll(editorState);
|
|
||||||
}
|
|
||||||
return KeyEventResult.ignored;
|
|
||||||
};
|
};
|
||||||
|
@ -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<TextNode>().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;
|
|
||||||
};
|
|
@ -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/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/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/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/internal_key_event_handlers/whitespace_handler.dart';
|
||||||
import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event.dart';
|
import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event.dart';
|
||||||
|
|
||||||
@ -102,6 +102,72 @@ List<ShortcutEvent> builtInShortcutEvents = [
|
|||||||
windowsCommand: 'ctrl+shift+arrow right',
|
windowsCommand: 'ctrl+shift+arrow right',
|
||||||
handler: cursorEndSelect,
|
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.
|
// TODO: split the keys.
|
||||||
ShortcutEvent(
|
ShortcutEvent(
|
||||||
key: 'Delete Text',
|
key: 'Delete Text',
|
||||||
@ -113,29 +179,11 @@ List<ShortcutEvent> builtInShortcutEvents = [
|
|||||||
command: 'slash',
|
command: 'slash',
|
||||||
handler: slashShortcutHandler,
|
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(
|
ShortcutEvent(
|
||||||
key: 'enter',
|
key: 'enter',
|
||||||
command: 'enter',
|
command: 'enter',
|
||||||
handler: enterWithoutShiftInTextNodesHandler,
|
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(
|
ShortcutEvent(
|
||||||
key: 'markdown',
|
key: 'markdown',
|
||||||
command: 'space',
|
command: 'space',
|
||||||
|
Loading…
Reference in New Issue
Block a user