Bläddra i källkod

feat: remove subtype render

Lucas.Xu 2 år sedan
förälder
incheckning
eb97141859

+ 74 - 67
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"
+        ],
+        "attributes": {
+          "heading": "h1"
+        }
+      },
+      {
+        "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 }
           }
           }
-        },
-        {
-          "type": "text",
-          "delta": [
-            { "insert": "Click the '?' at the bottom right for help and support."}
-          ],
-          "attributes": {}
+        ],
+        "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": {}
+      }
+    ]
+  }
+}

+ 32 - 12
frontend/app_flowy/packages/flowy_editor/example/lib/plugin/selected_text_node_widget.dart

@@ -20,6 +20,7 @@ class SelectedTextNodeBuilder extends NodeWidgetBuilder {
 
 
   @override
   @override
   Widget build(BuildContext buildContext) {
   Widget build(BuildContext buildContext) {
+    print('key -> $key');
     return _SelectedTextNodeWidget(
     return _SelectedTextNodeWidget(
       key: key,
       key: key,
       node: node,
       node: node,
@@ -100,9 +101,20 @@ class _SelectedTextNodeWidgetState extends State<_SelectedTextNodeWidget>
       // TODO: just handle upforward delete.
       // TODO: just handle upforward delete.
       if (textSelection != null) {
       if (textSelection != null) {
         if (textSelection.isCollapsed) {
         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 {
         } else {
           TransactionBuilder(editorState)
           TransactionBuilder(editorState)
             ..deleteText(node, textSelection.start,
             ..deleteText(node, textSelection.start,
@@ -117,6 +129,7 @@ class _SelectedTextNodeWidgetState extends State<_SelectedTextNodeWidget>
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
+    print('text rebuild $this');
     Widget richText;
     Widget richText;
     if (kDebugMode) {
     if (kDebugMode) {
       richText = DebuggableRichText(text: node.toTextSpan(), textKey: _textKey);
       richText = DebuggableRichText(text: node.toTextSpan(), textKey: _textKey);
@@ -127,7 +140,10 @@ class _SelectedTextNodeWidgetState extends State<_SelectedTextNodeWidget>
     return Column(
     return Column(
       crossAxisAlignment: CrossAxisAlignment.start,
       crossAxisAlignment: CrossAxisAlignment.start,
       children: [
       children: [
-        richText,
+        SizedBox(
+          width: MediaQuery.of(context).size.width,
+          child: richText,
+        ),
         if (node.children.isNotEmpty)
         if (node.children.isNotEmpty)
           ...node.children.map(
           ...node.children.map(
             (e) => editorState.renderPlugins.buildWidget(
             (e) => editorState.renderPlugins.buildWidget(
@@ -163,14 +179,18 @@ class _SelectedTextNodeWidgetState extends State<_SelectedTextNodeWidget>
     final position = TextPosition(offset: offset);
     final position = TextPosition(offset: offset);
     var cursorOffset = _renderParagraph.getOffsetForCaret(position, Rect.zero);
     var cursorOffset = _renderParagraph.getOffsetForCaret(position, Rect.zero);
     cursorOffset = _renderParagraph.localToGlobal(cursorOffset);
     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;
+    }
   }
   }
 }
 }
 
 

+ 2 - 8
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,
         textCapitalization: TextCapitalization.sentences,
       ),
       ),
     );
     );
-    debugPrint('selection: $selection');
     editorState.cursorSelection = _localSelectionToGlobal(node, selection);
     editorState.cursorSelection = _localSelectionToGlobal(node, selection);
     _textInputConnection
     _textInputConnection
       ?..show()
       ?..show()
@@ -182,9 +181,7 @@ class __TextNodeWidgetState extends State<_TextNodeWidget>
   }
   }
 
 
   @override
   @override
-  void performAction(TextInputAction action) {
-    debugPrint('action:$action');
-  }
+  void performAction(TextInputAction action) {}
 
 
   @override
   @override
   void performPrivateCommand(String action, Map<String, dynamic> data) {
   void performPrivateCommand(String action, Map<String, dynamic> data) {
@@ -207,13 +204,10 @@ class __TextNodeWidgetState extends State<_TextNodeWidget>
   }
   }
 
 
   @override
   @override
-  void updateEditingValue(TextEditingValue value) {
-    debugPrint('offset: ${value.selection}');
-  }
+  void updateEditingValue(TextEditingValue value) {}
 
 
   @override
   @override
   void updateEditingValueWithDeltas(List<TextEditingDelta> textEditingDeltas) {
   void updateEditingValueWithDeltas(List<TextEditingDelta> textEditingDeltas) {
-    debugPrint(textEditingDeltas.toString());
     for (final textDelta in textEditingDeltas) {
     for (final textDelta in textEditingDeltas) {
       if (textDelta is TextEditingDeltaInsertion) {
       if (textDelta is TextEditingDeltaInsertion) {
         TransactionBuilder(editorState)
         TransactionBuilder(editorState)

+ 2 - 4
frontend/app_flowy/packages/flowy_editor/lib/document/node.dart

@@ -186,8 +186,6 @@ class TextNode extends Node {
     return map;
     return map;
   }
   }
 
 
-  String toRawString() => _delta.operations
-      .whereType<TextInsert>()
-      .map((op) => op.content)
-      .toString();
+  String toRawString() =>
+      _delta.operations.whereType<TextInsert>().map((op) => op.content).join();
 }
 }

+ 4 - 0
frontend/app_flowy/packages/flowy_editor/lib/editor_state.dart

@@ -63,6 +63,10 @@ class EditorState {
   List<OverlayEntry> selectionOverlays = [];
   List<OverlayEntry> selectionOverlays = [];
 
 
   void updateCursor() {
   void updateCursor() {
+    selectionOverlays
+      ..forEach((element) => element.remove())
+      ..clear();
+
     if (tapOffset == null) {
     if (tapOffset == null) {
       return;
       return;
     }
     }

+ 1 - 0
frontend/app_flowy/packages/flowy_editor/lib/render/render_plugins.dart

@@ -51,6 +51,7 @@ class RenderPlugins {
     _nodeWidgetBuilders.removeWhere((key, _) => key == name);
     _nodeWidgetBuilders.removeWhere((key, _) => key == name);
   }
   }
 
 
+  @protected
   Widget buildWidget({
   Widget buildWidget({
     required NodeWidgetContext context,
     required NodeWidgetContext context,
     bool withSubtype = true,
     bool withSubtype = true,