diff --git a/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/whitespace_handler.dart b/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/whitespace_handler.dart index 59641bcf8a..b3642cc1a1 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/whitespace_handler.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/whitespace_handler.dart @@ -4,10 +4,15 @@ import 'package:flutter/services.dart'; import 'package:flowy_editor/document/node.dart'; import 'package:flowy_editor/document/position.dart'; import 'package:flowy_editor/document/selection.dart'; +import 'package:flowy_editor/editor_state.dart'; import 'package:flowy_editor/operation/transaction_builder.dart'; import 'package:flowy_editor/render/rich_text/rich_text_style.dart'; import 'package:flowy_editor/service/keyboard_service.dart'; +const _bulletedListSymbols = ['*', '-']; +const _checkboxListSymbols = ['[x]', '-[x]']; +const _unCheckboxListSymbols = ['[]', '-[]']; + FlowyKeyEventHandler whiteSpaceHandler = (editorState, event) { if (event.logicalKey != LogicalKeyboardKey.space) { return KeyEventResult.ignored; @@ -28,24 +33,99 @@ FlowyKeyEventHandler whiteSpaceHandler = (editorState, event) { return KeyEventResult.ignored; } - final builder = TransactionBuilder(editorState); final textNode = textNodes.first; final text = textNode.toRawString(); - if (text == '*' || text == '-') { - builder - ..deleteText(textNode, 0, 1) - ..updateNode(textNode, { - StyleKey.subtype: StyleKey.bulletedList, - }) - ..afterSelection = Selection.collapsed( - Position( - path: textNode.path, - offset: 0, - ), - ) - ..commit(); - return KeyEventResult.handled; + if ((_checkboxListSymbols + _unCheckboxListSymbols).any(text.startsWith)) { + return _toCheckboxList(editorState, textNode); + } else if (_bulletedListSymbols.any(text.startsWith)) { + return _toBulletedList(editorState, textNode); + } else if (_countOfSign(text) != 0) { + return _toHeadingStyle(editorState, textNode); } return KeyEventResult.ignored; }; + +KeyEventResult _toBulletedList(EditorState editorState, TextNode textNode) { + if (textNode.subtype == StyleKey.bulletedList) { + return KeyEventResult.ignored; + } + TransactionBuilder(editorState) + ..deleteText(textNode, 0, 1) + ..updateNode(textNode, { + StyleKey.subtype: StyleKey.bulletedList, + }) + ..afterSelection = Selection.collapsed( + Position( + path: textNode.path, + offset: 0, + ), + ) + ..commit(); + return KeyEventResult.handled; +} + +KeyEventResult _toCheckboxList(EditorState editorState, TextNode textNode) { + if (textNode.subtype == StyleKey.checkbox) { + return KeyEventResult.ignored; + } + final String symbol; + bool check = false; + final symbols = List.from(_checkboxListSymbols) + ..retainWhere(textNode.toRawString().startsWith); + if (symbols.isNotEmpty) { + symbol = symbols.first; + check = true; + } else { + symbol = (List.from(_unCheckboxListSymbols) + ..retainWhere(textNode.toRawString().startsWith)) + .first; + check = false; + } + + TransactionBuilder(editorState) + ..deleteText(textNode, 0, symbol.length) + ..updateNode(textNode, { + StyleKey.subtype: StyleKey.checkbox, + StyleKey.checkbox: check, + }) + ..afterSelection = Selection.collapsed( + Position( + path: textNode.path, + offset: 0, + ), + ) + ..commit(); + return KeyEventResult.handled; +} + +KeyEventResult _toHeadingStyle(EditorState editorState, TextNode textNode) { + final x = _countOfSign(textNode.toRawString()); + final hX = 'h$x'; + if (textNode.attributes.heading == hX) { + return KeyEventResult.ignored; + } + TransactionBuilder(editorState) + ..deleteText(textNode, 0, x) + ..updateNode(textNode, { + StyleKey.subtype: StyleKey.heading, + StyleKey.heading: hX, + }) + ..afterSelection = Selection.collapsed( + Position( + path: textNode.path, + offset: 0, + ), + ) + ..commit(); + return KeyEventResult.handled; +} + +int _countOfSign(String text) { + for (var i = 6; i >= 0; i--) { + if (text.startsWith('#' * i)) { + return i; + } + } + return 0; +}