瀏覽代碼

feat: pass BuildContext to NodeWidgetBuilder

Lucas.Xu 2 年之前
父節點
當前提交
05786d1255

+ 5 - 2
frontend/app_flowy/packages/flowy_editor/example/lib/main.dart

@@ -88,8 +88,11 @@ class _MyHomePageState extends State<MyHomePage> {
           } else {
             final data = Map<String, Object>.from(json.decode(snapshot.data!));
             final stateTree = StateTree.fromJson(data);
-            return renderPlugins.buildWidgetWithNode(
-              stateTree.root,
+            return renderPlugins.buildWidget(
+              NodeWidgetContext(
+                buildContext: context,
+                node: stateTree.root,
+              ),
             );
           }
         },

+ 16 - 4
frontend/app_flowy/packages/flowy_editor/example/lib/plugin/image_node_widget.dart

@@ -8,14 +8,26 @@ class ImageNodeBuilder extends NodeWidgetBuilder {
   String get src => node.attributes['image_src'] as String;
 
   @override
-  Widget build() {
-    final childrenWidget = buildChildren();
+  Widget build(BuildContext buildContext) {
     final image = Image.network(src);
-    if (childrenWidget != null) {
+    Widget? children;
+    if (node.children.isNotEmpty) {
+      children = Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: node.children
+            .map(
+              (e) => renderPlugins.buildWidget(
+                NodeWidgetContext(buildContext: buildContext, node: e),
+              ),
+            )
+            .toList(),
+      );
+    }
+    if (children != null) {
       return Column(
         children: [
           image,
-          childrenWidget,
+          children,
         ],
       );
     } else {

+ 18 - 4
frontend/app_flowy/packages/flowy_editor/example/lib/plugin/text_node_widget.dart

@@ -8,19 +8,33 @@ class TextNodeBuilder extends NodeWidgetBuilder {
   String get content => node.attributes['content'] as String;
 
   @override
-  Widget build() {
-    final childrenWidget = buildChildren();
+  Widget build(BuildContext buildContext) {
     final richText = SelectableText.rich(
       TextSpan(
         text: node.attributes['content'] as String,
         style: node.attributes.toTextStyle(),
       ),
     );
-    if (childrenWidget != null) {
+
+    Widget? children;
+    if (node.children.isNotEmpty) {
+      children = Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: node.children
+            .map(
+              (e) => renderPlugins.buildWidget(
+                NodeWidgetContext(buildContext: buildContext, node: e),
+              ),
+            )
+            .toList(),
+      );
+    }
+
+    if (children != null) {
       return Column(
         children: [
           richText,
-          childrenWidget,
+          children,
         ],
       );
     } else {

+ 4 - 16
frontend/app_flowy/packages/flowy_editor/lib/render/node_widget_builder.dart

@@ -9,21 +9,9 @@ class NodeWidgetBuilder<T extends Node> {
 
   NodeWidgetBuilder.create({required this.node, required this.renderPlugins});
 
-  Widget call() => build();
-  Widget build() => throw UnimplementedError();
-  Widget? buildChildren() {
-    if (node.children.isEmpty) {
-      return null;
-    }
+  Widget call(BuildContext buildContext) => build(buildContext);
 
-    // default layout
-    return Column(
-      crossAxisAlignment: CrossAxisAlignment.start,
-      children: node.children
-          .map(
-            (e) => renderPlugins.buildWidgetWithNode(e),
-          )
-          .toList(),
-    );
-  }
+  /// Render the current [Node]
+  /// and the layout style of [Node.Children].
+  Widget build(BuildContext buildContext) => throw UnimplementedError();
 }

+ 12 - 4
frontend/app_flowy/packages/flowy_editor/lib/render/render_plugins.dart

@@ -2,6 +2,12 @@ import 'package:flutter/material.dart';
 import '../document/node.dart';
 import 'node_widget_builder.dart';
 
+class NodeWidgetContext {
+  BuildContext buildContext;
+  Node node;
+  NodeWidgetContext({required this.buildContext, required this.node});
+}
+
 typedef NodeWidgetBuilderF<T extends Node, A extends NodeWidgetBuilder> = A
     Function({
   required T node,
@@ -28,13 +34,15 @@ class RenderPlugins {
     nodeWidgetBuilders.removeWhere((key, _) => key == name);
   }
 
-  Widget buildWidgetWithNode(Node node) {
-    final nodeWidgetBuilder = _nodeWidgetBuilder(node.type);
-    return nodeWidgetBuilder(node: node, renderPlugins: this)();
+  Widget buildWidget(NodeWidgetContext context) {
+    final nodeWidgetBuilder = _nodeWidgetBuilder(context.node.type);
+    return nodeWidgetBuilder(node: context.node, renderPlugins: this)(
+        context.buildContext);
   }
 
   NodeWidgetBuilderF _nodeWidgetBuilder(String name) {
-    assert(nodeWidgetBuilders.containsKey(name));
+    assert(nodeWidgetBuilders.containsKey(name),
+        'Could not query the builder with this $name');
     return nodeWidgetBuilders[name]!;
   }
 }