fix: accept multi-key combination for customizing shortcuts & removes duplicates (#5414)

This commit is contained in:
Mayur Mahajan 2024-05-27 06:27:51 +05:30 committed by GitHub
parent a8f136eda2
commit 8b6575d1ee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 57 additions and 29 deletions

View File

@ -56,7 +56,18 @@ final List<CommandShortcutEvent> commandShortcutEvents = [
customPasteCommand, customPasteCommand,
customCutCommand, customCutCommand,
...customTextAlignCommands, ...customTextAlignCommands,
...standardCommandShortcutEvents,
// remove standard shortcuts for copy, cut, paste, todo
...standardCommandShortcutEvents
..removeWhere(
(shortcut) => [
copyCommand,
cutCommand,
pasteCommand,
toggleTodoListCommand,
].contains(shortcut),
),
emojiShortcutEvent, emojiShortcutEvent,
]; ];
@ -90,7 +101,6 @@ class AppFlowyEditorPage extends StatefulWidget {
final String Function(Node)? placeholderText; final String Function(Node)? placeholderText;
/// Used to provide an initial selection on Page-load /// Used to provide an initial selection on Page-load
///
final Selection? initialSelection; final Selection? initialSelection;
final bool useViewInfoBloc; final bool useViewInfoBloc;
@ -111,15 +121,8 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
], ],
); );
late final List<CommandShortcutEvent> commandShortcutEvents = [ late final List<CommandShortcutEvent> cmdShortcutEvents = [
toggleToggleListCommand, ...commandShortcutEvents,
...localizedCodeBlockCommands,
customCopyCommand,
customPasteCommand,
customCutCommand,
...customTextAlignCommands,
...standardCommandShortcutEvents,
emojiShortcutEvent,
..._buildFindAndReplaceCommands(), ..._buildFindAndReplaceCommands(),
]; ];
@ -309,7 +312,7 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
), ),
// customize the shortcuts // customize the shortcuts
characterShortcutEvents: characterShortcutEvents, characterShortcutEvents: characterShortcutEvents,
commandShortcutEvents: commandShortcutEvents, commandShortcutEvents: cmdShortcutEvents,
// customize the context menu items // customize the context menu items
contextMenuItems: customContextMenuItems, contextMenuItems: customContextMenuItems,
// customize the header and footer. // customize the header and footer.
@ -401,7 +404,7 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
final customizeShortcuts = final customizeShortcuts =
await settingsShortcutService.getCustomizeShortcuts(); await settingsShortcutService.getCustomizeShortcuts();
await settingsShortcutService.updateCommandShortcuts( await settingsShortcutService.updateCommandShortcuts(
commandShortcutEvents, cmdShortcutEvents,
customizeShortcuts, customizeShortcuts,
); );
} }

View File

@ -32,6 +32,7 @@ class ShortcutsCubit extends Cubit<ShortcutsState> {
error: '', error: '',
), ),
); );
try { try {
final customizeShortcuts = await service.getCustomizeShortcuts(); final customizeShortcuts = await service.getCustomizeShortcuts();
await service.updateCommandShortcuts( await service.updateCommandShortcuts(
@ -40,7 +41,9 @@ class ShortcutsCubit extends Cubit<ShortcutsState> {
); );
//sort the shortcuts //sort the shortcuts
commandShortcutEvents.sort((a, b) => a.key.compareTo(b.key)); commandShortcutEvents.sort(
(a, b) => a.key.toLowerCase().compareTo(b.key.toLowerCase()),
);
emit( emit(
state.copyWith( state.copyWith(
@ -104,11 +107,11 @@ class ShortcutsCubit extends Cubit<ShortcutsState> {
} }
} }
///Checks if the new command is conflicting with other shortcut /// Checks if the new command is conflicting with other shortcut
///We also check using the key, whether this command is a codeblock /// We also check using the key, whether this command is a codeblock
///shortcut, if so we only check a conflict with other codeblock shortcut. /// shortcut, if so we only check a conflict with other codeblock shortcut.
String getConflict(CommandShortcutEvent currentShortcut, String command) { String getConflict(CommandShortcutEvent currentShortcut, String command) {
//check if currentShortcut is a codeblock shortcut. // check if currentShortcut is a codeblock shortcut.
final isCodeBlockCommand = currentShortcut.isCodeBlockCommand; final isCodeBlockCommand = currentShortcut.isCodeBlockCommand;
for (final e in state.commandShortcutEvents) { for (final e in state.commandShortcutEvents) {

View File

@ -84,7 +84,7 @@ class ShortcutsListView extends StatelessWidget {
} }
} }
class ShortcutsListTile extends StatelessWidget { class ShortcutsListTile extends StatefulWidget {
const ShortcutsListTile({ const ShortcutsListTile({
super.key, super.key,
required this.shortcutEvent, required this.shortcutEvent,
@ -92,6 +92,25 @@ class ShortcutsListTile extends StatelessWidget {
final CommandShortcutEvent shortcutEvent; final CommandShortcutEvent shortcutEvent;
@override
State<ShortcutsListTile> createState() => _ShortcutsListTileState();
}
class _ShortcutsListTileState extends State<ShortcutsListTile> {
late final TextEditingController controller;
@override
void initState() {
controller = TextEditingController(text: widget.shortcutEvent.command);
super.initState();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
@ -100,16 +119,16 @@ class ShortcutsListTile extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
child: FlowyText.medium( child: FlowyText.medium(
key: Key(shortcutEvent.key), key: Key(widget.shortcutEvent.key),
shortcutEvent.description!.capitalize(), widget.shortcutEvent.description!.capitalize(),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
), ),
FlowyTextButton( FlowyTextButton(
shortcutEvent.command, widget.shortcutEvent.command,
fontColor: AFThemeExtension.of(context).textColor, fontColor: AFThemeExtension.of(context).textColor,
fillColor: Colors.transparent, fillColor: Colors.transparent,
onPressed: () => showKeyListenerDialog(context), onPressed: () => showKeyListenerDialog(context, controller),
), ),
], ],
), ),
@ -120,8 +139,10 @@ class ShortcutsListTile extends StatelessWidget {
); );
} }
void showKeyListenerDialog(BuildContext widgetContext) { void showKeyListenerDialog(
final controller = TextEditingController(text: shortcutEvent.command); BuildContext widgetContext,
TextEditingController controller,
) {
showDialog( showDialog(
context: widgetContext, context: widgetContext,
builder: (builderContext) { builder: (builderContext) {
@ -131,9 +152,10 @@ class ShortcutsListTile extends StatelessWidget {
content: KeyboardListener( content: KeyboardListener(
focusNode: FocusNode(), focusNode: FocusNode(),
onKeyEvent: (key) { onKeyEvent: (key) {
if (key is! KeyDownEvent) return;
if (key.logicalKey == LogicalKeyboardKey.enter && if (key.logicalKey == LogicalKeyboardKey.enter &&
!HardwareKeyboard.instance.isShiftPressed) { !HardwareKeyboard.instance.isShiftPressed) {
if (controller.text == shortcutEvent.command) { if (controller.text == widget.shortcutEvent.command) {
_dismiss(builderContext); _dismiss(builderContext);
} }
if (formKey.currentState!.validate()) { if (formKey.currentState!.validate()) {
@ -166,12 +188,12 @@ class ShortcutsListTile extends StatelessWidget {
), ),
); );
}, },
).then((_) => controller.dispose()); );
} }
String? _validateForConflicts(BuildContext context, String command) { String? _validateForConflicts(BuildContext context, String command) {
final conflict = BlocProvider.of<ShortcutsCubit>(context).getConflict( final conflict = BlocProvider.of<ShortcutsCubit>(context).getConflict(
shortcutEvent, widget.shortcutEvent,
command, command,
); );
if (conflict.isEmpty) return null; if (conflict.isEmpty) return null;
@ -182,7 +204,7 @@ class ShortcutsListTile extends StatelessWidget {
} }
void _updateKey(BuildContext context, String command) { void _updateKey(BuildContext context, String command) {
shortcutEvent.updateCommand(command: command); widget.shortcutEvent.updateCommand(command: command);
BlocProvider.of<ShortcutsCubit>(context).updateAllShortcuts(); BlocProvider.of<ShortcutsCubit>(context).updateAllShortcuts();
} }