Ver código fonte

chore: add heading widget to example

Lucas.Xu 2 anos atrás
pai
commit
fef9e20e46

+ 39 - 24
frontend/app_flowy/packages/flowy_editor/example/assets/document.json

@@ -12,50 +12,65 @@
         {
         {
           "type": "text",
           "type": "text",
           "delta": [
           "delta": [
-            { "insert": "With " },
-            { "insert": "AppFlowy", "attributes": { "href": "https://www.appflowy.io/" } },
-            { "insert": ", you can build detailed lists of to-do’s for different projects while tracking the status of each one" }
+            { "insert": "👋 Welcome to AppFlowy!", "attributes": { "href": "https://www.appflowy.io/", "heading": "h1" } }
           ],
           ],
           "attributes": {
           "attributes": {
-            "subtype": "with-checkbox",
-            "font-size": 30,
-            "checkbox": false
+            "subtype": "with-heading",
+            "heading": "h1"
           }
           }
         },
         },
         {
         {
           "type": "text",
           "type": "text",
           "delta": [
           "delta": [
-            { "insert": "You can " },
-            { "insert": "host", "attributes": { "italic": true } },
-            { "insert": " " },
-            { "insert": "AppFlowy", "attributes": { "bold": true } },
-            { "insert": " " },
-            { "insert": "wherever you want", "attributes": { "underline": true }},
-            { "insert": "; no vendor lock-in." }
+            { "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": {
           "attributes": {
             "subtype": "with-checkbox",
             "subtype": "with-checkbox",
-            "text-type": "heading1",
-            "font-size": 30,
-            "checkbox": false
+            "checkbox": true
           }
           }
         },
         },
         {
         {
           "type": "text",
           "type": "text",
-          "delta": [{ "insert": "Design and modify AppFlowy your way with an open core codebase." }],
+          "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": {
           "attributes": {
-            "text-type": "heading1",
-            "font-size": 30
+            "subtype": "with-checkbox",
+            "checkbox": false
           }
           }
         },
         },
         {
         {
           "type": "text",
           "type": "text",
-          "delta": [{ "insert": "AppFlowy is built with Flutter and Rust. What does this mean? Faster development, better native experience, and more reliable performance." }],
-          "attributes": {
-            "text-type": "heading1",
-            "font-size": 30,
-            "content": "dddddddddddddddddddd"
+          "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": {}
         }
         }
       ]
       ]
     }
     }

+ 3 - 1
frontend/app_flowy/packages/flowy_editor/example/lib/main.dart

@@ -1,6 +1,7 @@
 import 'dart:convert';
 import 'dart:convert';
 
 
 import 'package:example/plugin/document_node_widget.dart';
 import 'package:example/plugin/document_node_widget.dart';
+import 'package:example/plugin/text_with_heading_node_widget.dart';
 import 'package:example/plugin/image_node_widget.dart';
 import 'package:example/plugin/image_node_widget.dart';
 import 'package:example/plugin/text_node_widget.dart';
 import 'package:example/plugin/text_node_widget.dart';
 import 'package:example/plugin/text_with_check_box_node_widget.dart';
 import 'package:example/plugin/text_with_check_box_node_widget.dart';
@@ -66,7 +67,8 @@ class _MyHomePageState extends State<MyHomePage> {
       ..register('editor', EditorNodeWidgetBuilder.create)
       ..register('editor', EditorNodeWidgetBuilder.create)
       ..register('text', TextNodeBuilder.create)
       ..register('text', TextNodeBuilder.create)
       ..register('image', ImageNodeBuilder.create)
       ..register('image', ImageNodeBuilder.create)
-      ..register('text/with-checkbox', TextWithCheckBoxNodeBuilder.create);
+      ..register('text/with-checkbox', TextWithCheckBoxNodeBuilder.create)
+      ..register('text/with-heading', TextWithHeadingNodeBuilder.create);
   }
   }
 
 
   @override
   @override

+ 1 - 11
frontend/app_flowy/packages/flowy_editor/example/lib/plugin/image_node_widget.dart

@@ -30,17 +30,7 @@ class _ImageNodeWidget extends StatelessWidget {
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
-    return GestureDetector(
-      child: _build(context),
-      onTap: () {
-        TransactionBuilder(editorState)
-          ..updateNode(node, {
-            'image_src':
-                "https://images.pexels.com/photos/9995076/pexels-photo-9995076.png?cs=srgb&dl=pexels-temmuz-uzun-9995076.jpg&fm=jpg&w=640&h=400"
-          })
-          ..commit();
-      },
-    );
+    return _build(context);
   }
   }
 
 
   Widget _build(BuildContext context) {
   Widget _build(BuildContext context) {

+ 20 - 1
frontend/app_flowy/packages/flowy_editor/example/lib/plugin/text_node_widget.dart

@@ -158,6 +158,8 @@ TextSpan _textInsertToTextSpan(TextInsert textInsert) {
   TextDecoration? decoration;
   TextDecoration? decoration;
   GestureRecognizer? gestureRecognizer;
   GestureRecognizer? gestureRecognizer;
   Color? color;
   Color? color;
+  Color highLightColor = Colors.transparent;
+  double fontSize = 16.0;
   final attributes = textInsert.attributes;
   final attributes = textInsert.attributes;
   if (attributes?['bold'] == true) {
   if (attributes?['bold'] == true) {
     fontWeight = FontWeight.bold;
     fontWeight = FontWeight.bold;
@@ -168,6 +170,12 @@ TextSpan _textInsertToTextSpan(TextInsert textInsert) {
   if (attributes?['underline'] == true) {
   if (attributes?['underline'] == true) {
     decoration = TextDecoration.underline;
     decoration = TextDecoration.underline;
   }
   }
+  if (attributes?['strikethrough'] == true) {
+    decoration = TextDecoration.lineThrough;
+  }
+  if (attributes?['highlight'] is String) {
+    highLightColor = Color(int.parse(attributes!['highlight']));
+  }
   if (attributes?['href'] is String) {
   if (attributes?['href'] is String) {
     color = const Color.fromARGB(255, 55, 120, 245);
     color = const Color.fromARGB(255, 55, 120, 245);
     decoration = TextDecoration.underline;
     decoration = TextDecoration.underline;
@@ -176,6 +184,16 @@ TextSpan _textInsertToTextSpan(TextInsert textInsert) {
         launchUrlString(attributes?['href']);
         launchUrlString(attributes?['href']);
       };
       };
   }
   }
+  final heading = attributes?['heading'] as String?;
+  if (heading != null) {
+    // TODO: make it better
+    if (heading == 'h1') {
+      fontSize = 30.0;
+    } else if (heading == 'h2') {
+      fontSize = 20.0;
+    }
+    fontWeight = FontWeight.bold;
+  }
   return TextSpan(
   return TextSpan(
     text: textInsert.content,
     text: textInsert.content,
     style: TextStyle(
     style: TextStyle(
@@ -183,7 +201,8 @@ TextSpan _textInsertToTextSpan(TextInsert textInsert) {
       fontStyle: fontStyle,
       fontStyle: fontStyle,
       decoration: decoration,
       decoration: decoration,
       color: color,
       color: color,
-      fontSize: 16,
+      fontSize: fontSize,
+      backgroundColor: highLightColor,
     ),
     ),
     recognizer: gestureRecognizer,
     recognizer: gestureRecognizer,
   );
   );

+ 45 - 0
frontend/app_flowy/packages/flowy_editor/example/lib/plugin/text_with_heading_node_widget.dart

@@ -0,0 +1,45 @@
+import 'package:flowy_editor/flowy_editor.dart';
+import 'package:flutter/material.dart';
+
+class TextWithHeadingNodeBuilder extends NodeWidgetBuilder {
+  TextWithHeadingNodeBuilder.create({
+    required super.editorState,
+    required super.node,
+  }) : super.create() {
+    nodeValidator = (node) => node.attributes.containsKey('heading');
+  }
+
+  String get heading => node.attributes['heading'] as String;
+  Widget buildPadding() {
+    if (heading == 'h1') {
+      return const Padding(
+        padding: EdgeInsets.only(top: 10),
+      );
+    } else if (heading == 'h1') {
+      return const Padding(
+        padding: EdgeInsets.only(top: 10),
+      );
+    }
+    return const Padding(
+      padding: EdgeInsets.only(top: 0),
+    );
+  }
+
+  @override
+  Widget build(BuildContext buildContext) {
+    return Column(
+      children: [
+        buildPadding(),
+        renderPlugins.buildWidget(
+          context: NodeWidgetContext(
+            buildContext: buildContext,
+            node: node,
+            editorState: editorState,
+          ),
+          withSubtype: false,
+        ),
+        buildPadding(),
+      ],
+    );
+  }
+}