fix: command shortcuts on the web platform should also respect the operating system
This commit is contained in:
parent
5c291320d7
commit
c9adbb1714
6 changed files with 71 additions and 166 deletions
|
|
@ -1,7 +1,4 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
typedef CommandShortcutEventHandler = KeyEventResult Function(
|
||||
|
|
@ -67,23 +64,17 @@ class CommandShortcutEvent {
|
|||
return;
|
||||
}
|
||||
var matched = false;
|
||||
if (kIsWeb) {
|
||||
// We shouldn't continue to run the below `else if` code in Web platform, it will throw an `_operatingSystem` exception.
|
||||
if (command != null && command.isNotEmpty) {
|
||||
this.command = command;
|
||||
matched = true;
|
||||
}
|
||||
} else if (Platform.isWindows &&
|
||||
if ((PlatformExtension.isWindows || PlatformExtension.isWebOnWindows) &&
|
||||
windowsCommand != null &&
|
||||
windowsCommand.isNotEmpty) {
|
||||
this.command = windowsCommand;
|
||||
matched = true;
|
||||
} else if (Platform.isMacOS &&
|
||||
} else if ((PlatformExtension.isMacOS || PlatformExtension.isWebOnMacOS) &&
|
||||
macOSCommand != null &&
|
||||
macOSCommand.isNotEmpty) {
|
||||
this.command = macOSCommand;
|
||||
matched = true;
|
||||
} else if (Platform.isLinux &&
|
||||
} else if ((PlatformExtension.isLinux || PlatformExtension.isWebOnLinux) &&
|
||||
linuxCommand != null &&
|
||||
linuxCommand.isNotEmpty) {
|
||||
this.command = linuxCommand;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:universal_html/html.dart' show window;
|
||||
|
||||
// TODO(Xazin): Refactor to honor `Theme.platform`
|
||||
extension PlatformExtension on Platform {
|
||||
static String get _webPlatform =>
|
||||
window.navigator.platform?.toLowerCase() ?? '';
|
||||
|
||||
/// Returns true if the operating system is macOS and not running on Web platform.
|
||||
static bool get isMacOS {
|
||||
if (kIsWeb) {
|
||||
return false;
|
||||
|
|
@ -11,6 +16,7 @@ extension PlatformExtension on Platform {
|
|||
return Platform.isMacOS;
|
||||
}
|
||||
|
||||
/// Returns true if the operating system is Windows and not running on Web platform.
|
||||
static bool get isWindows {
|
||||
if (kIsWeb) {
|
||||
return false;
|
||||
|
|
@ -18,6 +24,38 @@ extension PlatformExtension on Platform {
|
|||
return Platform.isWindows;
|
||||
}
|
||||
|
||||
/// Returns true if the operating system is Linux and not running on Web platform.
|
||||
static bool get isLinux {
|
||||
if (kIsWeb) {
|
||||
return false;
|
||||
}
|
||||
return Platform.isLinux;
|
||||
}
|
||||
|
||||
/// Returns true if the operating system is macOS and running on Web platform.
|
||||
static bool get isWebOnMacOS {
|
||||
if (!kIsWeb) {
|
||||
return false;
|
||||
}
|
||||
return _webPlatform.contains('mac') == true;
|
||||
}
|
||||
|
||||
/// Returns true if the operating system is Windows and running on Web platform.
|
||||
static bool get isWebOnWindows {
|
||||
if (!kIsWeb) {
|
||||
return false;
|
||||
}
|
||||
return _webPlatform.contains('windows') == true;
|
||||
}
|
||||
|
||||
/// Returns true if the operating system is Linux and running on Web platform.
|
||||
static bool get isWebOnLinux {
|
||||
if (!kIsWeb) {
|
||||
return false;
|
||||
}
|
||||
return _webPlatform.contains('linux') == true;
|
||||
}
|
||||
|
||||
static bool get isDesktopOrWeb {
|
||||
if (kIsWeb) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -1,150 +0,0 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy_editor/src/service/shortcut_event/keybinding.dart';
|
||||
import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
/// Defines the implementation of shortcut event.
|
||||
class ShortcutEvent {
|
||||
ShortcutEvent({
|
||||
required this.key,
|
||||
this.character,
|
||||
this.command,
|
||||
required this.handler,
|
||||
String? windowsCommand,
|
||||
String? macOSCommand,
|
||||
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(
|
||||
command: command,
|
||||
windowsCommand: windowsCommand,
|
||||
macOSCommand: macOSCommand,
|
||||
linuxCommand: linuxCommand,
|
||||
);
|
||||
}
|
||||
|
||||
/// The unique key.
|
||||
///
|
||||
/// Usually, uses the description as the key.
|
||||
final String key;
|
||||
|
||||
/// The string representation for the keyboard keys.
|
||||
///
|
||||
/// The following is the mapping relationship of modify key.
|
||||
/// ctrl: Ctrl
|
||||
/// meta: Command in macOS or Control in Windows.
|
||||
/// alt: Alt
|
||||
/// shift: Shift
|
||||
/// cmd: meta
|
||||
/// win: meta
|
||||
///
|
||||
/// Refer to [keyMapping] for other keys.
|
||||
///
|
||||
/// Uses ',' to split different keyboard key combinations.
|
||||
///
|
||||
/// Like, 'ctrl+c,cmd+c'
|
||||
///
|
||||
String? command;
|
||||
|
||||
String? character;
|
||||
|
||||
final ShortcutEventHandler handler;
|
||||
|
||||
List<Keybinding> get keybindings => _keybindings;
|
||||
List<Keybinding> _keybindings = [];
|
||||
|
||||
void updateCommand({
|
||||
String? command,
|
||||
String? windowsCommand,
|
||||
String? macOSCommand,
|
||||
String? linuxCommand,
|
||||
}) {
|
||||
if (command == null &&
|
||||
windowsCommand == null &&
|
||||
macOSCommand == null &&
|
||||
linuxCommand == null) {
|
||||
return;
|
||||
}
|
||||
var matched = false;
|
||||
if (kIsWeb) {
|
||||
// We shouldn't continue to run the below `else if` code in Web platform, it will throw an `_operatingSystem` exception.
|
||||
if (command != null && command.isNotEmpty) {
|
||||
this.command = command;
|
||||
matched = true;
|
||||
}
|
||||
} else if (Platform.isWindows &&
|
||||
windowsCommand != null &&
|
||||
windowsCommand.isNotEmpty) {
|
||||
this.command = windowsCommand;
|
||||
matched = true;
|
||||
} else if (Platform.isMacOS &&
|
||||
macOSCommand != null &&
|
||||
macOSCommand.isNotEmpty) {
|
||||
this.command = macOSCommand;
|
||||
matched = true;
|
||||
} else if (Platform.isLinux &&
|
||||
linuxCommand != null &&
|
||||
linuxCommand.isNotEmpty) {
|
||||
this.command = linuxCommand;
|
||||
matched = true;
|
||||
} else if (command != null && command.isNotEmpty) {
|
||||
this.command = command;
|
||||
matched = true;
|
||||
}
|
||||
|
||||
if (matched && this.command != null) {
|
||||
_keybindings = this
|
||||
.command!
|
||||
.split(',')
|
||||
.map((e) => Keybinding.parse(e))
|
||||
.toList(growable: false);
|
||||
}
|
||||
}
|
||||
|
||||
ShortcutEvent copyWith({
|
||||
String? key,
|
||||
String? command,
|
||||
ShortcutEventHandler? handler,
|
||||
}) {
|
||||
return ShortcutEvent(
|
||||
key: key ?? this.key,
|
||||
command: command ?? this.command,
|
||||
handler: handler ?? this.handler,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'ShortcutEvent(key: $key, command: $command, handler: $handler)';
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is ShortcutEvent &&
|
||||
other.key == key &&
|
||||
other.command == command &&
|
||||
other.handler == handler;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => key.hashCode ^ command.hashCode ^ handler.hashCode;
|
||||
}
|
||||
|
|
@ -38,6 +38,7 @@ dependencies:
|
|||
path: ^1.8.3
|
||||
diff_match_patch: ^0.4.1
|
||||
string_validator: ^1.0.0
|
||||
universal_html: ^2.2.4
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
|||
26
test/editor/util/platform_extension_test.dart
Normal file
26
test/editor/util/platform_extension_test.dart
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
group('platform extension', () {
|
||||
test('test safe platform judgement', () {
|
||||
if (!kIsWeb && Platform.isLinux) {
|
||||
expect(PlatformExtension.isLinux, true);
|
||||
expect(PlatformExtension.isWebOnLinux, false);
|
||||
}
|
||||
|
||||
if (!kIsWeb && Platform.isWindows) {
|
||||
expect(PlatformExtension.isWindows, true);
|
||||
expect(PlatformExtension.isWebOnWindows, false);
|
||||
}
|
||||
|
||||
if (!kIsWeb && Platform.isMacOS) {
|
||||
expect(PlatformExtension.isMacOS, true);
|
||||
expect(PlatformExtension.isWebOnMacOS, false);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -1,10 +1,9 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
|
||||
import '../../new/infra/testable_editor.dart';
|
||||
|
||||
|
|
@ -15,10 +14,10 @@ void main() async {
|
|||
|
||||
group('shortcut_event.dart', () {
|
||||
test('redefine shortcut event command', () {
|
||||
final shortcutEvent = ShortcutEvent(
|
||||
final shortcutEvent = CommandShortcutEvent(
|
||||
key: 'Sample',
|
||||
command: 'cmd+shift+alt+ctrl+a',
|
||||
handler: (editorState, event) {
|
||||
handler: (editorState) {
|
||||
return KeyEventResult.handled;
|
||||
},
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue