Browse Source

feat: trigger shortcut event by character (#2101)

Lucas.Xu 2 years ago
parent
commit
1536cdd15a

+ 8 - 1
frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/keyboard_service.dart

@@ -129,7 +129,7 @@ class _AppFlowyKeyboardState extends State<AppFlowyKeyboard>
 
 
     // TODO: use cache to optimize the searching time.
     // TODO: use cache to optimize the searching time.
     for (final shortcutEvent in widget.shortcutEvents) {
     for (final shortcutEvent in widget.shortcutEvents) {
-      if (shortcutEvent.keybindings.containsKeyEvent(event)) {
+      if (shortcutEvent.canRespondToRawKeyEvent(event)) {
         final result = shortcutEvent.handler(widget.editorState, event);
         final result = shortcutEvent.handler(widget.editorState, event);
         if (result == KeyEventResult.handled) {
         if (result == KeyEventResult.handled) {
           return KeyEventResult.handled;
           return KeyEventResult.handled;
@@ -157,3 +157,10 @@ class _AppFlowyKeyboardState extends State<AppFlowyKeyboard>
     return onKey(event);
     return onKey(event);
   }
   }
 }
 }
+
+extension on ShortcutEvent {
+  bool canRespondToRawKeyEvent(RawKeyEvent event) {
+    return ((character?.isNotEmpty ?? false) && character == event.character) ||
+        keybindings.containsKeyEvent(event);
+  }
+}

+ 2 - 2
frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart

@@ -247,7 +247,7 @@ List<ShortcutEvent> builtInShortcutEvents = [
   ),
   ),
   ShortcutEvent(
   ShortcutEvent(
     key: 'selection menu',
     key: 'selection menu',
-    command: 'slash,shift+slash',
+    character: '/',
     handler: slashShortcutHandler,
     handler: slashShortcutHandler,
   ),
   ),
   ShortcutEvent(
   ShortcutEvent(
@@ -304,7 +304,7 @@ List<ShortcutEvent> builtInShortcutEvents = [
   ),
   ),
   ShortcutEvent(
   ShortcutEvent(
     key: 'Underscore to italic',
     key: 'Underscore to italic',
-    command: 'shift+underscore',
+    character: '_',
     handler: underscoreToItalicHandler,
     handler: underscoreToItalicHandler,
   ),
   ),
   ShortcutEvent(
   ShortcutEvent(

+ 23 - 4
frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/shortcut_event/shortcut_event.dart

@@ -8,12 +8,29 @@ import 'package:flutter/foundation.dart';
 class ShortcutEvent {
 class ShortcutEvent {
   ShortcutEvent({
   ShortcutEvent({
     required this.key,
     required this.key,
-    required this.command,
+    this.character,
+    this.command,
     required this.handler,
     required this.handler,
     String? windowsCommand,
     String? windowsCommand,
     String? macOSCommand,
     String? macOSCommand,
     String? linuxCommand,
     String? linuxCommand,
   }) {
   }) {
+    // character and command cannot be null at the same time
+    assert(
+        !(character == null &&
+            command == null &&
+            windowsCommand == null &&
+            macOSCommand == null &&
+            linuxCommand == null),
+        'character and command cannot be null at the same time');
+    assert(
+        !(character != null &&
+            (command != null &&
+                windowsCommand != null &&
+                macOSCommand != null &&
+                linuxCommand != null)),
+        'character and command cannot be set at the same time');
+
     updateCommand(
     updateCommand(
       command: command,
       command: command,
       windowsCommand: windowsCommand,
       windowsCommand: windowsCommand,
@@ -43,7 +60,9 @@ class ShortcutEvent {
   ///
   ///
   /// Like, 'ctrl+c,cmd+c'
   /// Like, 'ctrl+c,cmd+c'
   ///
   ///
-  String command;
+  String? command;
+
+  String? character;
 
 
   final ShortcutEventHandler handler;
   final ShortcutEventHandler handler;
 
 
@@ -80,9 +99,9 @@ class ShortcutEvent {
       matched = true;
       matched = true;
     }
     }
 
 
-    if (matched) {
+    if (matched && this.command != null) {
       _keybindings = this
       _keybindings = this
-          .command
+          .command!
           .split(',')
           .split(',')
           .map((e) => Keybinding.parse(e))
           .map((e) => Keybinding.parse(e))
           .toList(growable: false);
           .toList(growable: false);

+ 33 - 33
frontend/appflowy_flutter/pubspec.lock

@@ -121,7 +121,7 @@ packages:
       name: build_daemon
       name: build_daemon
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "3.1.0"
+    version: "3.1.1"
   build_resolvers:
   build_resolvers:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -156,7 +156,7 @@ packages:
       name: built_value
       name: built_value
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "8.4.3"
+    version: "8.4.4"
   calendar_view:
   calendar_view:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
@@ -500,7 +500,7 @@ packages:
       name: flutter_plugin_android_lifecycle
       name: flutter_plugin_android_lifecycle
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.0.7"
+    version: "2.0.9"
   flutter_svg:
   flutter_svg:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -524,7 +524,7 @@ packages:
       name: fluttertoast
       name: fluttertoast
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "8.1.2"
+    version: "8.2.1"
   freezed:
   freezed:
     dependency: "direct dev"
     dependency: "direct dev"
     description:
     description:
@@ -599,7 +599,7 @@ packages:
       name: html
       name: html
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "0.15.1"
+    version: "0.15.2"
   http:
   http:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
@@ -709,7 +709,7 @@ packages:
       name: logger
       name: logger
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "1.1.0"
+    version: "1.3.0"
   logging:
   logging:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -779,7 +779,7 @@ packages:
       name: node_preamble
       name: node_preamble
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.0.1"
+    version: "2.0.2"
   package_config:
   package_config:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -856,35 +856,35 @@ packages:
       name: path_provider
       name: path_provider
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.0.12"
+    version: "2.0.14"
   path_provider_android:
   path_provider_android:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: path_provider_android
       name: path_provider_android
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.0.22"
+    version: "2.0.24"
   path_provider_foundation:
   path_provider_foundation:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: path_provider_foundation
       name: path_provider_foundation
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.1.1"
+    version: "2.2.0"
   path_provider_linux:
   path_provider_linux:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: path_provider_linux
       name: path_provider_linux
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.1.8"
+    version: "2.1.10"
   path_provider_platform_interface:
   path_provider_platform_interface:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: path_provider_platform_interface
       name: path_provider_platform_interface
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.0.5"
+    version: "2.0.6"
   path_provider_windows:
   path_provider_windows:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -898,7 +898,7 @@ packages:
       name: percent_indicator
       name: percent_indicator
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "4.2.2"
+    version: "4.2.3"
   petitparser:
   petitparser:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -919,7 +919,7 @@ packages:
       name: plugin_platform_interface
       name: plugin_platform_interface
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.1.3"
+    version: "2.1.4"
   pool:
   pool:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -1024,7 +1024,7 @@ packages:
       name: rich_clipboard_windows
       name: rich_clipboard_windows
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "1.0.1"
+    version: "1.0.2"
   screen_retriever:
   screen_retriever:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -1038,49 +1038,49 @@ packages:
       name: shared_preferences
       name: shared_preferences
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.0.17"
+    version: "2.0.20"
   shared_preferences_android:
   shared_preferences_android:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: shared_preferences_android
       name: shared_preferences_android
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.0.15"
+    version: "2.0.17"
   shared_preferences_foundation:
   shared_preferences_foundation:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: shared_preferences_foundation
       name: shared_preferences_foundation
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.1.3"
+    version: "2.1.5"
   shared_preferences_linux:
   shared_preferences_linux:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: shared_preferences_linux
       name: shared_preferences_linux
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.1.3"
+    version: "2.1.5"
   shared_preferences_platform_interface:
   shared_preferences_platform_interface:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: shared_preferences_platform_interface
       name: shared_preferences_platform_interface
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.1.0"
+    version: "2.1.1"
   shared_preferences_web:
   shared_preferences_web:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: shared_preferences_web
       name: shared_preferences_web
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.0.4"
+    version: "2.0.6"
   shared_preferences_windows:
   shared_preferences_windows:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: shared_preferences_windows
       name: shared_preferences_windows
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.1.3"
+    version: "2.1.5"
   shelf:
   shelf:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -1122,7 +1122,7 @@ packages:
       name: sized_context
       name: sized_context
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "1.0.0+1"
+    version: "1.0.0+4"
   sky_engine:
   sky_engine:
     dependency: transitive
     dependency: transitive
     description: flutter
     description: flutter
@@ -1155,7 +1155,7 @@ packages:
       name: source_maps
       name: source_maps
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "0.10.11"
+    version: "0.10.12"
   source_span:
   source_span:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -1295,56 +1295,56 @@ packages:
       name: url_launcher
       name: url_launcher
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "6.1.9"
+    version: "6.1.10"
   url_launcher_android:
   url_launcher_android:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: url_launcher_android
       name: url_launcher_android
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "6.0.23"
+    version: "6.0.26"
   url_launcher_ios:
   url_launcher_ios:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: url_launcher_ios
       name: url_launcher_ios
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "6.1.0"
+    version: "6.1.3"
   url_launcher_linux:
   url_launcher_linux:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: url_launcher_linux
       name: url_launcher_linux
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "3.0.2"
+    version: "3.0.4"
   url_launcher_macos:
   url_launcher_macos:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: url_launcher_macos
       name: url_launcher_macos
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "3.0.2"
+    version: "3.0.4"
   url_launcher_platform_interface:
   url_launcher_platform_interface:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: url_launcher_platform_interface
       name: url_launcher_platform_interface
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.1.1"
+    version: "2.1.2"
   url_launcher_web:
   url_launcher_web:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: url_launcher_web
       name: url_launcher_web
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "2.0.14"
+    version: "2.0.16"
   url_launcher_windows:
   url_launcher_windows:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: url_launcher_windows
       name: url_launcher_windows
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "3.0.3"
+    version: "3.0.5"
   uuid:
   uuid:
     dependency: transitive
     dependency: transitive
     description:
     description:
@@ -1407,7 +1407,7 @@ packages:
       name: window_manager
       name: window_manager
       url: "https://pub.dartlang.org"
       url: "https://pub.dartlang.org"
     source: hosted
     source: hosted
-    version: "0.3.0"
+    version: "0.3.1"
   xdg_directories:
   xdg_directories:
     dependency: transitive
     dependency: transitive
     description:
     description: