From 5085ea115f3ccb15fad583835e7901b31d88ea14 Mon Sep 17 00:00:00 2001 From: Mathias Mogensen <42929161+Xazin@users.noreply.github.com> Date: Thu, 13 Jul 2023 12:33:16 +0200 Subject: [PATCH] feat: alt+click to add block above (#2988) --- .../lib/core/raw_keyboard_extension.dart | 11 ++++++ .../document/presentation/editor_page.dart | 6 ++-- .../actions/block_action_add_button.dart | 34 +++++++++++++++---- frontend/resources/translations/en.json | 6 ++++ 4 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 frontend/appflowy_flutter/lib/core/raw_keyboard_extension.dart diff --git a/frontend/appflowy_flutter/lib/core/raw_keyboard_extension.dart b/frontend/appflowy_flutter/lib/core/raw_keyboard_extension.dart new file mode 100644 index 0000000000..c37c992421 --- /dev/null +++ b/frontend/appflowy_flutter/lib/core/raw_keyboard_extension.dart @@ -0,0 +1,11 @@ +import 'package:flutter/services.dart'; + +extension RawKeyboardExtension on RawKeyboard { + bool get isAltPressed => keysPressed.any( + (key) => [ + LogicalKeyboardKey.alt, + LogicalKeyboardKey.altLeft, + LogicalKeyboardKey.altRight, + ].contains(key), + ); +} diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart index efd2d8579d..d1ccf8823a 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart @@ -312,7 +312,7 @@ class _AppFlowyEditorPageState extends State { builder.actionBuilder = (context, state) { final padding = context.node.type == HeadingBlockKeys.type ? const EdgeInsets.only(top: 8.0) - : const EdgeInsets.all(0); + : EdgeInsets.zero; return Padding( padding: padding, child: BlockActionList( @@ -320,9 +320,7 @@ class _AppFlowyEditorPageState extends State { blockComponentState: state, editorState: widget.editorState, actions: actions, - showSlashMenu: () => showSlashMenu( - widget.editorState, - ), + showSlashMenu: () => showSlashMenu(widget.editorState), ), ); }; diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_add_button.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_add_button.dart index f05c6244c8..2a5435bfa7 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_add_button.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_add_button.dart @@ -1,6 +1,12 @@ +import 'dart:io'; + +import 'package:appflowy/core/raw_keyboard_extension.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/block_action_button.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; class BlockAddButton extends StatelessWidget { const BlockAddButton({ @@ -21,25 +27,41 @@ class BlockAddButton extends StatelessWidget { Widget build(BuildContext context) { return BlockActionButton( svgName: 'editor/add', - richMessage: const TextSpan( + richMessage: TextSpan( children: [ TextSpan( - // todo: l10n. - text: 'Click to add below', + text: LocaleKeys.blockActions_addBelowTooltip.tr(), + ), + const TextSpan(text: '\n'), + TextSpan( + text: Platform.isMacOS + ? LocaleKeys.blockActions_addAboveMacCmd.tr() + : LocaleKeys.blockActions_addAboveCmd.tr(), + ), + const TextSpan(text: ' '), + TextSpan( + text: LocaleKeys.blockActions_addAboveTooltip.tr(), ), ], ), onTap: () { + final isAltPressed = RawKeyboard.instance.isAltPressed; + final transaction = editorState.transaction; - // if the current block is not a empty paragraph block, then insert a new block below the current block. + + // If the current block is not an empty paragraph block, + // then insert a new block above/below the current block. final node = blockComponentContext.node; if (node.type != ParagraphBlockKeys.type || (node.delta?.isNotEmpty ?? true)) { - transaction.insertNode(node.path.next, paragraphNode()); - transaction.afterSelection = Selection.collapse(node.path.next, 0); + final path = isAltPressed ? node.path : node.path.next; + + transaction.insertNode(path, paragraphNode()); + transaction.afterSelection = Selection.collapse(path, 0); } else { transaction.afterSelection = Selection.collapse(node.path, 0); } + // show the slash menu. editorState.apply(transaction).then( (_) => WidgetsBinding.instance.addPostFrameCallback( diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 00723a2e27..2939393b09 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -8,6 +8,12 @@ "title": "Title", "youCanAlso": "You can also", "and": "and", + "blockActions": { + "addBelowTooltip": "Click to add below", + "addAboveCmd": "Alt+click", + "addAboveMacCmd": "Option+click", + "addAboveTooltip": "to add above" + }, "signUp": { "buttonText": "Sign Up", "title": "Sign Up to @:appName",