diff --git a/frontend/app_flowy/packages/flowy_editor/example/lib/main.dart b/frontend/app_flowy/packages/flowy_editor/example/lib/main.dart index ae1f1dbcb9..68a10783a6 100644 --- a/frontend/app_flowy/packages/flowy_editor/example/lib/main.dart +++ b/frontend/app_flowy/packages/flowy_editor/example/lib/main.dart @@ -62,11 +62,11 @@ class _MyHomePageState extends State { renderPlugins ..register( 'text', - textNodeWidgetBuilder, + TextNodeBuilder.create, ) ..register( 'image', - imageNodeWidgetBuilder, + ImageNodeBuilder.create, ); } diff --git a/frontend/app_flowy/packages/flowy_editor/example/lib/plugin/image_node_widget.dart b/frontend/app_flowy/packages/flowy_editor/example/lib/plugin/image_node_widget.dart index 5d4ac64dec..02d6d8fc85 100644 --- a/frontend/app_flowy/packages/flowy_editor/example/lib/plugin/image_node_widget.dart +++ b/frontend/app_flowy/packages/flowy_editor/example/lib/plugin/image_node_widget.dart @@ -1,55 +1,25 @@ import 'package:flowy_editor/flowy_editor.dart'; import 'package:flutter/material.dart'; -NodeWidgetBuilder imageNodeWidgetBuilder = - (node, renderPlugins) => ImageNodeWidget( - node: node, - renderPlugins: renderPlugins, - ); +class ImageNodeBuilder extends NodeWidgetBuilder { + ImageNodeBuilder.create({required super.node, required super.renderPlugins}) + : super.create(); -class ImageNodeWidget extends BaseNodeWidget { - const ImageNodeWidget({ - super.key, - required super.node, - required super.renderPlugins, - }); - - @override - State createState() => _ImageNodeWidgetState(); -} - -class _ImageNodeWidgetState extends State { - Node get node => widget.node; String get src => node.attributes['image_src'] as String; @override - Widget build(BuildContext context) { - final childWidget = renderChildren(); + Widget build() { + final childrenWidget = buildChildren(); final image = Image.network(src); - if (childWidget != null) { + if (childrenWidget != null) { return Column( - children: [image, childWidget], + children: [ + image, + childrenWidget, + ], ); } else { return image; } } - - // manage children's render - Widget? renderChildren() { - if (node.children.isEmpty) { - return null; - } - - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: node.children - .map( - (e) => widget.renderPlugins.buildWidgetWithNode( - e, - ), - ) - .toList(), - ); - } } 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 6b1617d7d8..c73878c269 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 @@ -1,61 +1,32 @@ import 'package:flutter/material.dart'; import 'package:flowy_editor/flowy_editor.dart'; -NodeWidgetBuilder textNodeWidgetBuilder = - (node, renderPlugins) => TextNodeWidget( - node: node, - renderPlugins: renderPlugins, - ); +class TextNodeBuilder extends NodeWidgetBuilder { + TextNodeBuilder.create({required super.node, required super.renderPlugins}) + : super.create(); -class TextNodeWidget extends BaseNodeWidget { - const TextNodeWidget({ - super.key, - required super.node, - required super.renderPlugins, - }); + String get content => node.attributes['content'] as String; @override - State createState() => _TextNodeWidgetState(); -} - -class _TextNodeWidgetState extends State { - Node get node => widget.node; - - @override - Widget build(BuildContext context) { - final childWidget = renderChildren(); - final richText = RichText( - text: TextSpan( + Widget build() { + final childrenWidget = buildChildren(); + final richText = SelectableText.rich( + TextSpan( text: node.attributes['content'] as String, style: node.attributes.toTextStyle(), ), ); - if (childWidget != null) { + if (childrenWidget != null) { return Column( - children: [richText, childWidget], + children: [ + richText, + childrenWidget, + ], ); } else { return richText; } } - - // manage children's render - Widget? renderChildren() { - if (node.children.isEmpty) { - return null; - } - - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: node.children - .map( - (e) => widget.renderPlugins.buildWidgetWithNode( - e, - ), - ) - .toList(), - ); - } } extension on Attributes { diff --git a/frontend/app_flowy/packages/flowy_editor/lib/flowy_editor.dart b/frontend/app_flowy/packages/flowy_editor/lib/flowy_editor.dart index c56cdc1b30..b16fe82273 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/flowy_editor.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/flowy_editor.dart @@ -4,4 +4,4 @@ export 'package:flowy_editor/document/state_tree.dart'; export 'package:flowy_editor/document/node.dart'; export 'package:flowy_editor/document/path.dart'; export 'package:flowy_editor/render/render_plugins.dart'; -export 'package:flowy_editor/render/base_node_widget.dart'; +export 'package:flowy_editor/render/node_widget_builder.dart'; diff --git a/frontend/app_flowy/packages/flowy_editor/lib/render/base_node_widget.dart b/frontend/app_flowy/packages/flowy_editor/lib/render/base_node_widget.dart deleted file mode 100644 index 0838846a6a..0000000000 --- a/frontend/app_flowy/packages/flowy_editor/lib/render/base_node_widget.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import '../document/node.dart'; -import '../render/render_plugins.dart'; - -class BaseNodeWidget extends StatefulWidget { - final T node; - final RenderPlugins renderPlugins; - - const BaseNodeWidget({ - Key? key, - required this.node, - required this.renderPlugins, - }) : super(key: key); - - @override - State createState() => _BaseNodeWidgetState(); -} - -class _BaseNodeWidgetState extends State { - @override - Widget build(BuildContext context) { - throw UnimplementedError(); - } -} diff --git a/frontend/app_flowy/packages/flowy_editor/lib/render/node_widget_builder.dart b/frontend/app_flowy/packages/flowy_editor/lib/render/node_widget_builder.dart new file mode 100644 index 0000000000..3d32c52bab --- /dev/null +++ b/frontend/app_flowy/packages/flowy_editor/lib/render/node_widget_builder.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; + +import '../document/node.dart'; +import '../render/render_plugins.dart'; + +class NodeWidgetBuilder { + final T node; + final RenderPlugins renderPlugins; + + NodeWidgetBuilder.create({required this.node, required this.renderPlugins}); + + Widget call() => build(); + Widget build() => throw UnimplementedError(); + Widget? buildChildren() { + if (node.children.isEmpty) { + return null; + } + + // default layout + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: node.children + .map( + (e) => renderPlugins.buildWidgetWithNode(e), + ) + .toList(), + ); + } +} 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 f192281cd2..84e3d894b7 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 @@ -1,21 +1,22 @@ -import 'package:flutter/widgets.dart'; +import 'package:flutter/material.dart'; import '../document/node.dart'; -import '../render/base_node_widget.dart'; +import 'node_widget_builder.dart'; -typedef NodeWidgetBuilder = BaseNodeWidget Function( - T node, - RenderPlugins plugins, -); +typedef NodeWidgetBuilderF = A + Function({ + required T node, + required RenderPlugins renderPlugins, +}); // unused -typedef NodeBuilder = T Function(Node node); +// typedef NodeBuilder = T Function(Node node); class RenderPlugins { - Map nodeWidgetBuilders = {}; + Map nodeWidgetBuilders = {}; // unused // Map nodeBuilders = {}; - void register(String name, NodeWidgetBuilder builder) { + void register(String name, NodeWidgetBuilderF builder) { nodeWidgetBuilders[name] = builder; } @@ -23,12 +24,12 @@ class RenderPlugins { nodeWidgetBuilders.removeWhere((key, _) => key == name); } - BaseNodeWidget buildWidgetWithNode(Node node) { + Widget buildWidgetWithNode(Node node) { final nodeWidgetBuilder = _nodeWidgetBuilder(node.type); - return nodeWidgetBuilder(node, this); + return nodeWidgetBuilder(node: node, renderPlugins: this)(); } - NodeWidgetBuilder _nodeWidgetBuilder(String name) { + NodeWidgetBuilderF _nodeWidgetBuilder(String name) { assert(nodeWidgetBuilders.containsKey(name)); return nodeWidgetBuilders[name]!; }