Skip to content

Commit 347698f

Browse files
feat: support aligning the text block using shortcuts (#4319)
1 parent db2e231 commit 347698f

File tree

4 files changed

+133
-6
lines changed

4 files changed

+133
-6
lines changed

frontend/appflowy_flutter/integration_test/document/document_alignment_test.dart

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import 'package:appflowy/generated/flowy_svgs.g.dart';
2+
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
23
import 'package:appflowy_editor/appflowy_editor.dart';
4+
import 'package:flutter/services.dart';
35
import 'package:flutter_test/flutter_test.dart';
46
import 'package:integration_test/integration_test.dart';
57

8+
import '../util/keyboard.dart';
69
import '../util/util.dart';
710

811
void main() {
@@ -42,5 +45,51 @@ void main() {
4245
await tester.tapButtonWithFlowySvgData(FlowySvgs.toolbar_align_left_s);
4346
expect(first.attributes[blockComponentAlign], 'left');
4447
});
48+
49+
testWidgets('edit alignment using shortcut', (tester) async {
50+
await tester.initializeAppFlowy();
51+
await tester.tapGoButton();
52+
53+
// click the first line of the readme
54+
await tester.editor.tapLineOfEditorAt(0);
55+
56+
await tester.pumpAndSettle();
57+
58+
final editorState = tester.editor.getCurrentEditorState();
59+
final first = editorState.getNodeAtPath([0])!;
60+
61+
// expect to see text aligned to the right
62+
await FlowyTestKeyboard.simulateKeyDownEvent(
63+
[
64+
LogicalKeyboardKey.control,
65+
LogicalKeyboardKey.shift,
66+
LogicalKeyboardKey.keyR,
67+
],
68+
tester: tester,
69+
);
70+
expect(first.attributes[blockComponentAlign], rightAlignmentKey);
71+
72+
// expect to see text aligned to the center
73+
await FlowyTestKeyboard.simulateKeyDownEvent(
74+
[
75+
LogicalKeyboardKey.control,
76+
LogicalKeyboardKey.shift,
77+
LogicalKeyboardKey.keyE,
78+
],
79+
tester: tester,
80+
);
81+
expect(first.attributes[blockComponentAlign], centerAlignmentKey);
82+
83+
// expect to see text aligned to the left
84+
await FlowyTestKeyboard.simulateKeyDownEvent(
85+
[
86+
LogicalKeyboardKey.control,
87+
LogicalKeyboardKey.shift,
88+
LogicalKeyboardKey.keyL,
89+
],
90+
tester: tester,
91+
);
92+
expect(first.attributes[blockComponentAlign], leftAlignmentKey);
93+
});
4594
});
4695
}

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:appflowy/plugins/document/application/doc_bloc.dart';
22
import 'package:appflowy/plugins/document/presentation/editor_configuration.dart';
3+
import 'package:appflowy/plugins/document/presentation/editor_plugins/align_toolbar_item/custom_text_align_command.dart';
34
import 'package:appflowy/plugins/document/presentation/editor_plugins/background_color/theme_background_color.dart';
45
import 'package:appflowy/plugins/document/presentation/editor_plugins/base/page_reference_commands.dart';
56
import 'package:appflowy/plugins/document/presentation/editor_plugins/i18n/editor_i18n.dart';
@@ -31,6 +32,7 @@ final List<CommandShortcutEvent> commandShortcutEvents = [
3132
customCopyCommand,
3233
customPasteCommand,
3334
customCutCommand,
35+
...customTextAlignCommands,
3436
...standardCommandShortcutEvents,
3537
];
3638

@@ -86,6 +88,7 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
8688
customCopyCommand,
8789
customPasteCommand,
8890
customCutCommand,
91+
...customTextAlignCommands,
8992
...standardCommandShortcutEvents,
9093
..._buildFindAndReplaceCommands(),
9194
];

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/align_toolbar_item/align_toolbar_item.dart

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
77
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
88
import 'package:flutter/material.dart';
99

10+
const String leftAlignmentKey = 'left';
11+
const String centerAlignmentKey = 'center';
12+
const String rightAlignmentKey = 'right';
13+
1014
final alignToolbarItem = ToolbarItem(
1115
id: 'editor.align',
1216
group: 4,
@@ -23,13 +27,13 @@ final alignToolbarItem = ToolbarItem(
2327

2428
bool isHighlight = false;
2529
FlowySvgData data = FlowySvgs.toolbar_align_left_s;
26-
if (isSatisfyCondition((value) => value == 'left')) {
30+
if (isSatisfyCondition((value) => value == leftAlignmentKey)) {
2731
isHighlight = true;
2832
data = FlowySvgs.toolbar_align_left_s;
29-
} else if (isSatisfyCondition((value) => value == 'center')) {
33+
} else if (isSatisfyCondition((value) => value == centerAlignmentKey)) {
3034
isHighlight = true;
3135
data = FlowySvgs.toolbar_align_center_s;
32-
} else if (isSatisfyCondition((value) => value == 'right')) {
36+
} else if (isSatisfyCondition((value) => value == rightAlignmentKey)) {
3337
isHighlight = true;
3438
data = FlowySvgs.toolbar_align_right_s;
3539
}
@@ -121,19 +125,19 @@ class _AlignButtons extends StatelessWidget {
121125
_AlignButton(
122126
icon: FlowySvgs.toolbar_align_left_s,
123127
tooltips: LocaleKeys.document_plugins_optionAction_left.tr(),
124-
onTap: () => onAlignChanged('left'),
128+
onTap: () => onAlignChanged(leftAlignmentKey),
125129
),
126130
const _Divider(),
127131
_AlignButton(
128132
icon: FlowySvgs.toolbar_align_center_s,
129133
tooltips: LocaleKeys.document_plugins_optionAction_center.tr(),
130-
onTap: () => onAlignChanged('center'),
134+
onTap: () => onAlignChanged(centerAlignmentKey),
131135
),
132136
const _Divider(),
133137
_AlignButton(
134138
icon: FlowySvgs.toolbar_align_right_s,
135139
tooltips: LocaleKeys.document_plugins_optionAction_right.tr(),
136-
onTap: () => onAlignChanged('right'),
140+
onTap: () => onAlignChanged(rightAlignmentKey),
137141
),
138142
const HSpace(4),
139143
],
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
2+
import 'package:appflowy_editor/appflowy_editor.dart';
3+
import 'package:flutter/material.dart';
4+
5+
final List<CommandShortcutEvent> customTextAlignCommands = [
6+
customTextLeftAlignCommand,
7+
customTextCenterAlignCommand,
8+
customTextRightAlignCommand,
9+
];
10+
11+
/// Windows / Linux : ctrl + shift + l
12+
/// macOS : ctrl + shift + l
13+
/// Allows the user to align text to the left
14+
///
15+
/// - support
16+
/// - desktop
17+
/// - web
18+
///
19+
final CommandShortcutEvent customTextLeftAlignCommand = CommandShortcutEvent(
20+
key: 'Align text to the left',
21+
command: 'ctrl+shift+l',
22+
handler: (editorState) => _textAlignHandler(editorState, leftAlignmentKey),
23+
);
24+
25+
/// Windows / Linux : ctrl + shift + e
26+
/// macOS : ctrl + shift + e
27+
/// Allows the user to align text to the center
28+
///
29+
/// - support
30+
/// - desktop
31+
/// - web
32+
///
33+
final CommandShortcutEvent customTextCenterAlignCommand = CommandShortcutEvent(
34+
key: 'Align text to the center',
35+
command: 'ctrl+shift+e',
36+
handler: (editorState) => _textAlignHandler(editorState, centerAlignmentKey),
37+
);
38+
39+
/// Windows / Linux : ctrl + shift + r
40+
/// macOS : ctrl + shift + r
41+
/// Allows the user to align text to the right
42+
///
43+
/// - support
44+
/// - desktop
45+
/// - web
46+
///
47+
final CommandShortcutEvent customTextRightAlignCommand = CommandShortcutEvent(
48+
key: 'Align text to the right',
49+
command: 'ctrl+shift+r',
50+
handler: (editorState) => _textAlignHandler(editorState, rightAlignmentKey),
51+
);
52+
53+
KeyEventResult _textAlignHandler(EditorState editorState, String align) {
54+
final Selection? selection = editorState.selection;
55+
56+
if (selection == null) {
57+
return KeyEventResult.ignored;
58+
}
59+
60+
editorState.updateNode(
61+
selection,
62+
(node) => node.copyWith(
63+
attributes: {
64+
...node.attributes,
65+
blockComponentAlign: align,
66+
},
67+
),
68+
);
69+
70+
return KeyEventResult.handled;
71+
}

0 commit comments

Comments
 (0)