From eb97141859594b789da08a2d5140659c9e30ff81 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Thu, 21 Jul 2022 20:04:25 +0800 Subject: [PATCH] feat: remove subtype render --- .../flowy_editor/example/assets/document.json | 143 +++++++++--------- .../lib/plugin/selected_text_node_widget.dart | 44 ++++-- .../example/lib/plugin/text_node_widget.dart | 10 +- .../flowy_editor/lib/document/node.dart | 6 +- .../flowy_editor/lib/editor_state.dart | 4 + .../lib/render/render_plugins.dart | 1 + 6 files changed, 116 insertions(+), 92 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_editor/example/assets/document.json b/frontend/app_flowy/packages/flowy_editor/example/assets/document.json index f74672345f..16635261db 100644 --- a/frontend/app_flowy/packages/flowy_editor/example/assets/document.json +++ b/frontend/app_flowy/packages/flowy_editor/example/assets/document.json @@ -1,71 +1,78 @@ { - "document": { - "type": "editor", - "attributes": {}, - "children": [ - { - "type": "text", - "delta": [ - { "insert": "👋 Welcome to AppFlowy!", "attributes": { "href": "https://www.appflowy.io/", "heading": "h1" } } - ], - "attributes": { - "subtype": "with-heading", - "heading": "h1" + "document": { + "type": "editor", + "attributes": {}, + "children": [ + { + "type": "text", + "delta": [ + { + "insert": "👋 Welcome to AppFlowy!", + "attributes": { + "href": "https://www.appflowy.io/", + "heading": "h1" + } } - }, - { - "type": "text", - "delta": [ - { "insert": "Here are the basics", "attributes": { "heading": "h2" } } - ], - "attributes": { - "subtype": "with-heading", - "heading": "h2" - } - }, - { - "type": "text", - "delta": [ - { "insert": "Click anywhere and just start typing." } - ], - "attributes": { - "subtype": "with-checkbox", - "checkbox": true - } - }, - { - "type": "text", - "delta": [ - { "insert": "Highlight", "attributes": { "highlight": "0xFFFFFF00" } }, - { "insert": " Click anywhere and just start typing" }, - { "insert": " any text, and use the menu at the bottom to " }, - { "insert": "style", "attributes": { "italic": true } }, - { "insert": " your ", "attributes": { "bold": true } }, - { "insert": "writing", "attributes": { "underline": true } }, - { "insert": " howeverv you like.", "attributes": { "strikethrough": true } } - ], - "attributes": { - "subtype": "with-checkbox", - "checkbox": false - } - }, - { - "type": "text", - "delta": [ - { "insert": "Have a question? ", "attributes": { "heading": "h2" } } - ], - "attributes": { - "subtype": "with-heading", - "heading": "h2" - } - }, - { - "type": "text", - "delta": [ - { "insert": "Click the '?' at the bottom right for help and support."} - ], - "attributes": {} + ], + "attributes": { + "heading": "h1" } - ] - } - } \ No newline at end of file + }, + { + "type": "text", + "delta": [ + { "insert": "Here are the basics", "attributes": { "heading": "h2" } } + ], + "attributes": { + "heading": "h2" + } + }, + { + "type": "text", + "delta": [{ "insert": "Click anywhere and just start typing." }], + "attributes": { + "checkbox": true + } + }, + { + "type": "text", + "delta": [ + { + "insert": "Highlight", + "attributes": { "highlight": "0xFFFFFF00" } + }, + { "insert": " Click anywhere and just start typing" }, + { "insert": " any text, and use the menu at the bottom to " }, + { "insert": "style", "attributes": { "italic": true } }, + { "insert": " your ", "attributes": { "bold": true } }, + { "insert": "writing", "attributes": { "underline": true } }, + { + "insert": " howeverv you like.", + "attributes": { "strikethrough": true } + } + ], + "attributes": { + "checkbox": false + } + }, + { + "type": "text", + "delta": [ + { "insert": "Have a question? ", "attributes": { "heading": "h2" } } + ], + "attributes": { + "heading": "h2" + } + }, + { + "type": "text", + "delta": [ + { + "insert": "Click the '?' at the bottom right for help and support." + } + ], + "attributes": {} + } + ] + } +} diff --git a/frontend/app_flowy/packages/flowy_editor/example/lib/plugin/selected_text_node_widget.dart b/frontend/app_flowy/packages/flowy_editor/example/lib/plugin/selected_text_node_widget.dart index 4d04bfb660..5eb8a1b40f 100644 --- a/frontend/app_flowy/packages/flowy_editor/example/lib/plugin/selected_text_node_widget.dart +++ b/frontend/app_flowy/packages/flowy_editor/example/lib/plugin/selected_text_node_widget.dart @@ -20,6 +20,7 @@ class SelectedTextNodeBuilder extends NodeWidgetBuilder { @override Widget build(BuildContext buildContext) { + print('key -> $key'); return _SelectedTextNodeWidget( key: key, node: node, @@ -100,9 +101,20 @@ class _SelectedTextNodeWidgetState extends State<_SelectedTextNodeWidget> // TODO: just handle upforward delete. if (textSelection != null) { if (textSelection.isCollapsed) { - TransactionBuilder(editorState) - ..deleteText(node, textSelection.start - 1, 1) - ..commit(); + print(node.toRawString()); + print('is empty ${node.toRawString().isEmpty}'); + if (textSelection.baseOffset == 0 && node.toRawString().isEmpty) { + TransactionBuilder(editorState) + ..deleteNode(node) + ..commit(); + } else { + TransactionBuilder(editorState) + ..deleteText(node, textSelection.start - 1, 1) + ..commit(); + final rect = _computeCursorRect(textSelection.baseOffset - 1); + editorState.tapOffset = rect.center; + editorState.updateCursor(); + } } else { TransactionBuilder(editorState) ..deleteText(node, textSelection.start, @@ -117,6 +129,7 @@ class _SelectedTextNodeWidgetState extends State<_SelectedTextNodeWidget> @override Widget build(BuildContext context) { + print('text rebuild $this'); Widget richText; if (kDebugMode) { richText = DebuggableRichText(text: node.toTextSpan(), textKey: _textKey); @@ -127,7 +140,10 @@ class _SelectedTextNodeWidgetState extends State<_SelectedTextNodeWidget> return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - richText, + SizedBox( + width: MediaQuery.of(context).size.width, + child: richText, + ), if (node.children.isNotEmpty) ...node.children.map( (e) => editorState.renderPlugins.buildWidget( @@ -163,14 +179,18 @@ class _SelectedTextNodeWidgetState extends State<_SelectedTextNodeWidget> final position = TextPosition(offset: offset); var cursorOffset = _renderParagraph.getOffsetForCaret(position, Rect.zero); cursorOffset = _renderParagraph.localToGlobal(cursorOffset); - final cursorHeight = _renderParagraph.getFullHeightForCaret(position)!; - const cursorWidth = 2; - return Rect.fromLTWH( - cursorOffset.dx - (cursorWidth / 2), - cursorOffset.dy, - cursorWidth.toDouble(), - cursorHeight.toDouble(), - ); + final cursorHeight = _renderParagraph.getFullHeightForCaret(position); + if (cursorHeight != null) { + const cursorWidth = 2; + return Rect.fromLTWH( + cursorOffset.dx - (cursorWidth / 2), + cursorOffset.dy, + cursorWidth.toDouble(), + cursorHeight.toDouble(), + ); + } else { + return Rect.zero; + } } } diff --git a/frontend/app_flowy/packages/flowy_editor/example/lib/plugin/text_node_widget.dart b/frontend/app_flowy/packages/flowy_editor/example/lib/plugin/text_node_widget.dart index 911a6179be..c265dc6254 100644 --- a/frontend/app_flowy/packages/flowy_editor/example/lib/plugin/text_node_widget.dart +++ b/frontend/app_flowy/packages/flowy_editor/example/lib/plugin/text_node_widget.dart @@ -103,7 +103,6 @@ class __TextNodeWidgetState extends State<_TextNodeWidget> textCapitalization: TextCapitalization.sentences, ), ); - debugPrint('selection: $selection'); editorState.cursorSelection = _localSelectionToGlobal(node, selection); _textInputConnection ?..show() @@ -182,9 +181,7 @@ class __TextNodeWidgetState extends State<_TextNodeWidget> } @override - void performAction(TextInputAction action) { - debugPrint('action:$action'); - } + void performAction(TextInputAction action) {} @override void performPrivateCommand(String action, Map data) { @@ -207,13 +204,10 @@ class __TextNodeWidgetState extends State<_TextNodeWidget> } @override - void updateEditingValue(TextEditingValue value) { - debugPrint('offset: ${value.selection}'); - } + void updateEditingValue(TextEditingValue value) {} @override void updateEditingValueWithDeltas(List textEditingDeltas) { - debugPrint(textEditingDeltas.toString()); for (final textDelta in textEditingDeltas) { if (textDelta is TextEditingDeltaInsertion) { TransactionBuilder(editorState) diff --git a/frontend/app_flowy/packages/flowy_editor/lib/document/node.dart b/frontend/app_flowy/packages/flowy_editor/lib/document/node.dart index 8c75eca360..8010a40646 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/document/node.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/document/node.dart @@ -186,8 +186,6 @@ class TextNode extends Node { return map; } - String toRawString() => _delta.operations - .whereType() - .map((op) => op.content) - .toString(); + String toRawString() => + _delta.operations.whereType().map((op) => op.content).join(); } diff --git a/frontend/app_flowy/packages/flowy_editor/lib/editor_state.dart b/frontend/app_flowy/packages/flowy_editor/lib/editor_state.dart index 9ce17e26de..1d3f63a4ba 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/editor_state.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/editor_state.dart @@ -63,6 +63,10 @@ class EditorState { List selectionOverlays = []; void updateCursor() { + selectionOverlays + ..forEach((element) => element.remove()) + ..clear(); + if (tapOffset == null) { return; } diff --git a/frontend/app_flowy/packages/flowy_editor/lib/render/render_plugins.dart b/frontend/app_flowy/packages/flowy_editor/lib/render/render_plugins.dart index efe5865d64..5d62c7b246 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/render/render_plugins.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/render/render_plugins.dart @@ -51,6 +51,7 @@ class RenderPlugins { _nodeWidgetBuilders.removeWhere((key, _) => key == name); } + @protected Widget buildWidget({ required NodeWidgetContext context, bool withSubtype = true,