From c5fa9039b4f7b2715642ec4d592367f8ade2263b Mon Sep 17 00:00:00 2001 From: Morn Date: Wed, 26 Feb 2025 10:06:28 +0800 Subject: [PATCH] fix: add shortcut to create Inline Math Equation (#7401) * fix: add shortcut to create Math Equation(#7331) * chore: update code Co-authored-by: Lucas --------- Co-authored-by: Lucas --- .../document/document_alignment_test.dart | 2 +- ...cument_with_inline_math_equation_test.dart | 51 +++++++++++++ .../custom_text_align_command.dart | 9 +-- .../math_equation/math_equation_shortcut.dart | 74 +++++++++++++++++++ .../shortcuts/command_shortcuts.dart | 2 + .../document/presentation/editor_style.dart | 4 + .../pages/settings_shortcuts_view.dart | 5 ++ frontend/resources/translations/en.json | 1 + 8 files changed, 142 insertions(+), 6 deletions(-) create mode 100644 frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/math_equation/math_equation_shortcut.dart diff --git a/frontend/appflowy_flutter/integration_test/desktop/document/document_alignment_test.dart b/frontend/appflowy_flutter/integration_test/desktop/document/document_alignment_test.dart index d95d907881..ea8db6fdad 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/document/document_alignment_test.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/document/document_alignment_test.dart @@ -75,7 +75,7 @@ void main() { [ LogicalKeyboardKey.control, LogicalKeyboardKey.shift, - LogicalKeyboardKey.keyE, + LogicalKeyboardKey.keyC, ], tester: tester, withKeyUp: true, diff --git a/frontend/appflowy_flutter/integration_test/desktop/document/document_with_inline_math_equation_test.dart b/frontend/appflowy_flutter/integration_test/desktop/document/document_with_inline_math_equation_test.dart index 45f688bd58..906b5ab69c 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/document/document_with_inline_math_equation_test.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/document/document_with_inline_math_equation_test.dart @@ -4,6 +4,7 @@ import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; @@ -163,5 +164,55 @@ void main() { lessThan(5), ); }); + + testWidgets('insert inline math equation by shortcut', (tester) async { + await tester.initializeAppFlowy(); + await tester.tapAnonymousSignInButton(); + + // create a new document + await tester.createNewPageWithNameUnderParent( + name: 'insert inline math equation by shortcut', + ); + + // tap the first line of the document + await tester.editor.tapLineOfEditorAt(0); + // insert a inline page + const formula = 'E = MC ^ 2'; + await tester.ime.insertText(formula); + await tester.editor.updateSelection( + Selection.single(path: [0], startOffset: 0, endOffset: formula.length), + ); + + // mock key event + await tester.simulateKeyEvent( + LogicalKeyboardKey.keyE, + isShiftPressed: true, + isControlPressed: true, + ); + + // expect to see the math equation block + final inlineMathEquation = find.byType(InlineMathEquation); + expect(inlineMathEquation, findsOneWidget); + + await tester.editor.tapLineOfEditorAt(0); + const text = 'Hello World'; + await tester.ime.insertText(text); + + final inlineText = find.textContaining(text, findRichText: true); + expect(inlineText, findsOneWidget); + + // the text should be in the same line with the math equation + final inlineMathEquationPosition = tester.getRect(inlineMathEquation); + final textPosition = tester.getRect(inlineText); + // allow 5px difference + expect( + (textPosition.top - inlineMathEquationPosition.top).abs(), + lessThan(5), + ); + expect( + (textPosition.bottom - inlineMathEquationPosition.bottom).abs(), + lessThan(5), + ); + }); }); } 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 index 9fe78591c3..bc3f5cffa1 100644 --- 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 @@ -1,9 +1,8 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; final List customTextAlignCommands = [ customTextLeftAlignCommand, @@ -26,8 +25,8 @@ final CommandShortcutEvent customTextLeftAlignCommand = CommandShortcutEvent( handler: (editorState) => _textAlignHandler(editorState, leftAlignmentKey), ); -/// Windows / Linux : ctrl + shift + e -/// macOS : ctrl + shift + e +/// Windows / Linux : ctrl + shift + c +/// macOS : ctrl + shift + c /// Allows the user to align text to the center /// /// - support @@ -36,7 +35,7 @@ final CommandShortcutEvent customTextLeftAlignCommand = CommandShortcutEvent( /// final CommandShortcutEvent customTextCenterAlignCommand = CommandShortcutEvent( key: 'Align text to the center', - command: 'ctrl+shift+e', + command: 'ctrl+shift+c', getDescription: LocaleKeys.settings_shortcutsPage_commands_textAlignCenter.tr, handler: (editorState) => _textAlignHandler(editorState, centerAlignmentKey), ); diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/math_equation/math_equation_shortcut.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/math_equation/math_equation_shortcut.dart new file mode 100644 index 0000000000..9c9fe7905b --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/math_equation/math_equation_shortcut.dart @@ -0,0 +1,74 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; + +/// Windows / Linux : ctrl + shift + e +/// macOS : cmd + shift + e +/// Allows the user to insert math equation by shortcut +/// +/// - support +/// - desktop +/// - web +/// +final CommandShortcutEvent insertInlineMathEquationCommand = + CommandShortcutEvent( + key: 'Insert inline math equation', + command: 'ctrl+shift+e', + macOSCommand: 'cmd+shift+e', + getDescription: LocaleKeys.document_plugins_mathEquation_name.tr, + handler: (editorState) { + final selection = editorState.selection; + if (selection == null || selection.isCollapsed || !selection.isSingle) { + return KeyEventResult.ignored; + } + final node = editorState.getNodeAtPath(selection.start.path); + final delta = node?.delta; + if (node == null || delta == null) { + return KeyEventResult.ignored; + } + if (node.delta == null || !toolbarItemWhiteList.contains(node.type)) { + return KeyEventResult.ignored; + } + final transaction = editorState.transaction; + final nodes = editorState.getNodesInSelection(selection); + final isHighlight = nodes.allSatisfyInSelection(selection, (delta) { + return delta.everyAttributes( + (attributes) => attributes[InlineMathEquationKeys.formula] != null, + ); + }); + if (isHighlight) { + final formula = delta + .slice(selection.startIndex, selection.endIndex) + .whereType() + .firstOrNull + ?.attributes?[InlineMathEquationKeys.formula]; + assert(formula != null); + if (formula == null) { + return KeyEventResult.ignored; + } + // clear the format + transaction.replaceText( + node, + selection.startIndex, + selection.length, + formula, + attributes: {}, + ); + } else { + final text = editorState.getTextInSelection(selection).join(); + transaction.replaceText( + node, + selection.startIndex, + selection.length, + MentionBlockKeys.mentionChar, + attributes: { + InlineMathEquationKeys.formula: text, + }, + ); + } + editorState.apply(transaction); + return KeyEventResult.handled; + }, +); diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/shortcuts/command_shortcuts.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/shortcuts/command_shortcuts.dart index 1f409255c6..aedfcff432 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/shortcuts/command_shortcuts.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/shortcuts/command_shortcuts.dart @@ -1,5 +1,6 @@ import 'package:appflowy/generated/locale_keys.g.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/math_equation/math_equation_shortcut.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/shortcuts/custom_delete_command.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/undo_redo/custom_undo_redo_commands.dart'; @@ -39,6 +40,7 @@ List commandShortcutEvents = [ ...customTextAlignCommands, customDeleteCommand, + insertInlineMathEquationCommand, // remove standard shortcuts for copy, cut, paste, todo ...standardCommandShortcutEvents diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart index 716296e51f..c5df72dd0c 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart @@ -494,6 +494,10 @@ class EditorStyleCustomizer { 'italic': (LocaleKeys.toolbar_italic.tr(), 'I'), 'strikethrough': (LocaleKeys.toolbar_strike.tr(), 'Shift+S'), 'code': (LocaleKeys.toolbar_inlineCode.tr(), 'E'), + 'editor.inline_math_equation': ( + LocaleKeys.document_plugins_createInlineMathEquation.tr(), + 'Shift+E' + ), }; final markdownItemIds = markdownItemTooltips.keys.toSet(); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_shortcuts_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_shortcuts_view.dart index 1db39b8fda..3552205ba4 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_shortcuts_view.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_shortcuts_view.dart @@ -5,6 +5,7 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/base/strin import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/custom_copy_command.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/custom_cut_command.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/custom_paste_command.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/math_equation/math_equation_shortcut.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/toggle/toggle_block_shortcuts.dart'; import 'package:appflowy/workspace/application/settings/shortcuts/settings_shortcuts_cubit.dart'; import 'package:appflowy/workspace/application/settings/shortcuts/settings_shortcuts_service.dart'; @@ -597,6 +598,10 @@ extension CommandLabel on CommandShortcutEvent { label = LocaleKeys.settings_shortcutsPage_keybindings_alignCenter.tr(); } else if (key == customTextRightAlignCommand.key) { label = LocaleKeys.settings_shortcutsPage_keybindings_alignRight.tr(); + } else if (key == insertInlineMathEquationCommand.key) { + label = LocaleKeys + .settings_shortcutsPage_keybindings_insertInlineMathEquation + .tr(); } else if (key == undoCommand.key) { label = LocaleKeys.settings_shortcutsPage_keybindings_undo.tr(); } else if (key == redoCommand.key) { diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index a618801894..bd054dabd3 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -759,6 +759,7 @@ "alignLeft": "Align text left", "alignCenter": "Align text center", "alignRight": "Align text right", + "insertInlineMathEquation": "Insert inline math eqaution", "undo": "Undo", "redo": "Redo", "convertToParagraph": "Convert block to paragraph",