feat: implement markdown input, like, #, *, -, -[]

This commit is contained in:
Lucas.Xu 2022-08-08 15:33:11 +08:00
parent 7855e5403c
commit 19fc154681

View File

@ -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,11 +33,24 @@ FlowyKeyEventHandler whiteSpaceHandler = (editorState, event) {
return KeyEventResult.ignored;
}
final builder = TransactionBuilder(editorState);
final textNode = textNodes.first;
final text = textNode.toRawString();
if (text == '*' || text == '-') {
builder
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,
@ -45,7 +63,69 @@ FlowyKeyEventHandler whiteSpaceHandler = (editorState, event) {
)
..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<String>.from(_checkboxListSymbols)
..retainWhere(textNode.toRawString().startsWith);
if (symbols.isNotEmpty) {
symbol = symbols.first;
check = true;
} else {
symbol = (List<String>.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;
}