From 347698f68f8a59c5757c3b082c71c9a5e3dc2380 Mon Sep 17 00:00:00 2001 From: Jayaprakash Date: Tue, 9 Jan 2024 18:57:08 +0530 Subject: [PATCH] feat: support aligning the text block using shortcuts (#4319) --- .../document/document_alignment_test.dart | 49 +++++++++++++ .../document/presentation/editor_page.dart | 3 + .../align_toolbar_item.dart | 16 +++-- .../custom_text_align_command.dart | 71 +++++++++++++++++++ 4 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/align_toolbar_item/custom_text_align_command.dart diff --git a/frontend/appflowy_flutter/integration_test/document/document_alignment_test.dart b/frontend/appflowy_flutter/integration_test/document/document_alignment_test.dart index 1a4752ead8..7ce09c559d 100644 --- a/frontend/appflowy_flutter/integration_test/document/document_alignment_test.dart +++ b/frontend/appflowy_flutter/integration_test/document/document_alignment_test.dart @@ -1,8 +1,11 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import '../util/keyboard.dart'; import '../util/util.dart'; void main() { @@ -42,5 +45,51 @@ void main() { await tester.tapButtonWithFlowySvgData(FlowySvgs.toolbar_align_left_s); expect(first.attributes[blockComponentAlign], 'left'); }); + + testWidgets('edit alignment using shortcut', (tester) async { + await tester.initializeAppFlowy(); + await tester.tapGoButton(); + + // click the first line of the readme + await tester.editor.tapLineOfEditorAt(0); + + await tester.pumpAndSettle(); + + final editorState = tester.editor.getCurrentEditorState(); + final first = editorState.getNodeAtPath([0])!; + + // expect to see text aligned to the right + await FlowyTestKeyboard.simulateKeyDownEvent( + [ + LogicalKeyboardKey.control, + LogicalKeyboardKey.shift, + LogicalKeyboardKey.keyR, + ], + tester: tester, + ); + expect(first.attributes[blockComponentAlign], rightAlignmentKey); + + // expect to see text aligned to the center + await FlowyTestKeyboard.simulateKeyDownEvent( + [ + LogicalKeyboardKey.control, + LogicalKeyboardKey.shift, + LogicalKeyboardKey.keyE, + ], + tester: tester, + ); + expect(first.attributes[blockComponentAlign], centerAlignmentKey); + + // expect to see text aligned to the left + await FlowyTestKeyboard.simulateKeyDownEvent( + [ + LogicalKeyboardKey.control, + LogicalKeyboardKey.shift, + LogicalKeyboardKey.keyL, + ], + tester: tester, + ); + expect(first.attributes[blockComponentAlign], leftAlignmentKey); + }); }); } 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 c7dd5fe9ef..d6c763a0dd 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart @@ -1,5 +1,6 @@ import 'package:appflowy/plugins/document/application/doc_bloc.dart'; import 'package:appflowy/plugins/document/presentation/editor_configuration.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/align_toolbar_item/custom_text_align_command.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/background_color/theme_background_color.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/base/page_reference_commands.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/i18n/editor_i18n.dart'; @@ -31,6 +32,7 @@ final List commandShortcutEvents = [ customCopyCommand, customPasteCommand, customCutCommand, + ...customTextAlignCommands, ...standardCommandShortcutEvents, ]; @@ -86,6 +88,7 @@ class _AppFlowyEditorPageState extends State { customCopyCommand, customPasteCommand, customCutCommand, + ...customTextAlignCommands, ...standardCommandShortcutEvents, ..._buildFindAndReplaceCommands(), ]; diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/align_toolbar_item/align_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/align_toolbar_item/align_toolbar_item.dart index fe0a6d2f10..52cc4f39ba 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/align_toolbar_item/align_toolbar_item.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/align_toolbar_item/align_toolbar_item.dart @@ -7,6 +7,10 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; import 'package:flutter/material.dart'; +const String leftAlignmentKey = 'left'; +const String centerAlignmentKey = 'center'; +const String rightAlignmentKey = 'right'; + final alignToolbarItem = ToolbarItem( id: 'editor.align', group: 4, @@ -23,13 +27,13 @@ final alignToolbarItem = ToolbarItem( bool isHighlight = false; FlowySvgData data = FlowySvgs.toolbar_align_left_s; - if (isSatisfyCondition((value) => value == 'left')) { + if (isSatisfyCondition((value) => value == leftAlignmentKey)) { isHighlight = true; data = FlowySvgs.toolbar_align_left_s; - } else if (isSatisfyCondition((value) => value == 'center')) { + } else if (isSatisfyCondition((value) => value == centerAlignmentKey)) { isHighlight = true; data = FlowySvgs.toolbar_align_center_s; - } else if (isSatisfyCondition((value) => value == 'right')) { + } else if (isSatisfyCondition((value) => value == rightAlignmentKey)) { isHighlight = true; data = FlowySvgs.toolbar_align_right_s; } @@ -121,19 +125,19 @@ class _AlignButtons extends StatelessWidget { _AlignButton( icon: FlowySvgs.toolbar_align_left_s, tooltips: LocaleKeys.document_plugins_optionAction_left.tr(), - onTap: () => onAlignChanged('left'), + onTap: () => onAlignChanged(leftAlignmentKey), ), const _Divider(), _AlignButton( icon: FlowySvgs.toolbar_align_center_s, tooltips: LocaleKeys.document_plugins_optionAction_center.tr(), - onTap: () => onAlignChanged('center'), + onTap: () => onAlignChanged(centerAlignmentKey), ), const _Divider(), _AlignButton( icon: FlowySvgs.toolbar_align_right_s, tooltips: LocaleKeys.document_plugins_optionAction_right.tr(), - onTap: () => onAlignChanged('right'), + onTap: () => onAlignChanged(rightAlignmentKey), ), const HSpace(4), ], diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/align_toolbar_item/custom_text_align_command.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/align_toolbar_item/custom_text_align_command.dart new file mode 100644 index 0000000000..620dbc335c --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/align_toolbar_item/custom_text_align_command.dart @@ -0,0 +1,71 @@ +import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flutter/material.dart'; + +final List customTextAlignCommands = [ + customTextLeftAlignCommand, + customTextCenterAlignCommand, + customTextRightAlignCommand, +]; + +/// Windows / Linux : ctrl + shift + l +/// macOS : ctrl + shift + l +/// Allows the user to align text to the left +/// +/// - support +/// - desktop +/// - web +/// +final CommandShortcutEvent customTextLeftAlignCommand = CommandShortcutEvent( + key: 'Align text to the left', + command: 'ctrl+shift+l', + handler: (editorState) => _textAlignHandler(editorState, leftAlignmentKey), +); + +/// Windows / Linux : ctrl + shift + e +/// macOS : ctrl + shift + e +/// Allows the user to align text to the center +/// +/// - support +/// - desktop +/// - web +/// +final CommandShortcutEvent customTextCenterAlignCommand = CommandShortcutEvent( + key: 'Align text to the center', + command: 'ctrl+shift+e', + handler: (editorState) => _textAlignHandler(editorState, centerAlignmentKey), +); + +/// Windows / Linux : ctrl + shift + r +/// macOS : ctrl + shift + r +/// Allows the user to align text to the right +/// +/// - support +/// - desktop +/// - web +/// +final CommandShortcutEvent customTextRightAlignCommand = CommandShortcutEvent( + key: 'Align text to the right', + command: 'ctrl+shift+r', + handler: (editorState) => _textAlignHandler(editorState, rightAlignmentKey), +); + +KeyEventResult _textAlignHandler(EditorState editorState, String align) { + final Selection? selection = editorState.selection; + + if (selection == null) { + return KeyEventResult.ignored; + } + + editorState.updateNode( + selection, + (node) => node.copyWith( + attributes: { + ...node.attributes, + blockComponentAlign: align, + }, + ), + ); + + return KeyEventResult.handled; +}