Browse Source

feat: implement bold text in toolbar service

Lucas.Xu 2 years ago
parent
commit
ba78f0073d

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

@@ -178,7 +178,7 @@ class TextNode extends Node {
   }) : _delta = delta;
 
   TextNode.empty()
-      : _delta = Delta([TextInsert('')]),
+      : _delta = Delta([TextInsert(' ')]),
         super(
           type: 'text',
           children: LinkedList(),

+ 36 - 38
frontend/app_flowy/packages/flowy_editor/lib/render/selection/toolbar_widget.dart

@@ -1,43 +1,35 @@
 import 'package:flowy_editor/editor_state.dart';
 import 'package:flowy_editor/infra/flowy_svg.dart';
+import 'package:flowy_editor/render/rich_text/rich_text_style.dart';
+import 'package:flowy_editor/service/default_text_operations/format_rich_text_style.dart';
 import 'package:flutter/material.dart';
 
-typedef ToolbarEventHandler = void Function(
-    EditorState editorState, String eventName);
-
-typedef ToolbarEventHandlers = List<Map<String, ToolbarEventHandler>>;
-ToolbarEventHandlers defaultToolbarEventHandlers = [
-  {
-    'bold': ((editorState, eventName) {}),
-    'italic': ((editorState, eventName) {}),
-    'strikethrough': ((editorState, eventName) {}),
-    'underline': ((editorState, eventName) {}),
-    'quote': ((editorState, eventName) {}),
-    'number_list': ((editorState, eventName) {}),
-    'bulleted_list': ((editorState, eventName) {}),
-  }
-];
-
-ToolbarEventHandlers defaultListToolbarEventHandlers = [
-  {
-    'h1': ((editorState, eventName) {}),
-  },
-  {
-    'h2': ((editorState, eventName) {}),
-  },
-  {
-    'h3': ((editorState, eventName) {}),
-  },
-  {
-    'bulleted_list': ((editorState, eventName) {}),
-  },
-  {
-    'quote': ((editorState, eventName) {}),
-  }
+typedef ToolbarEventHandler = void Function(EditorState editorState);
+
+typedef ToolbarEventHandlers = Map<String, ToolbarEventHandler>;
+
+ToolbarEventHandlers defaultToolbarEventHandlers = {
+  'bold': ((editorState) {
+    formatRichTextStyle(editorState, {StyleKey.bold: true});
+  }),
+  'italic': ((editorState) {}),
+  'strikethrough': ((editorState) {}),
+  'underline': ((editorState) {}),
+  'quote': ((editorState) {}),
+  'number_list': ((editorState) {}),
+  'bulleted_list': ((editorState) {}),
+};
+
+List<String> defaultListToolbarEventNames = [
+  'H1',
+  'H2',
+  'H3',
+  'B-List',
+  'N-List',
 ];
 
 class ToolbarWidget extends StatefulWidget {
-  ToolbarWidget({
+  const ToolbarWidget({
     Key? key,
     required this.editorState,
     required this.layerLink,
@@ -137,7 +129,7 @@ class _ToolbarWidgetState extends State<ToolbarWidget> {
       preferBelow: false,
       message: name,
       child: GestureDetector(
-        onTap: onTap ?? () => debugPrint('toolbar tap $name'),
+        onTap: onTap ?? () => _onTap(name),
         child: SizedBox.fromSize(
           size: width != null
               ? Size(width, toolbarHeight)
@@ -154,9 +146,7 @@ class _ToolbarWidgetState extends State<ToolbarWidget> {
 
   void _onTapListToolbar(BuildContext context) {
     // TODO: implement more detailed UI.
-    final items = defaultListToolbarEventHandlers
-        .map((handler) => handler.keys.first)
-        .toList(growable: false);
+    final items = defaultListToolbarEventNames;
     final renderBox =
         _listToolbarKey.currentContext?.findRenderObject() as RenderBox;
     final offset = renderBox
@@ -198,7 +188,7 @@ class _ToolbarWidgetState extends State<ToolbarWidget> {
                     ),
                   ),
                   onTap: () {
-                    debugPrint('tap on $index');
+                    _onTap(items[index]);
                   },
                 );
               }),
@@ -210,6 +200,14 @@ class _ToolbarWidgetState extends State<ToolbarWidget> {
     Overlay.of(context)?.insert(_listToolbarOverlay!);
   }
 
+  void _onTap(String eventName) {
+    if (defaultToolbarEventHandlers.containsKey(eventName)) {
+      defaultToolbarEventHandlers[eventName]!(widget.editorState);
+      return;
+    }
+    assert(false, 'Could not find the event handler for $eventName');
+  }
+
   void _onSelectionChange() {
     _listToolbarOverlay?.remove();
     _listToolbarOverlay = null;

+ 32 - 23
frontend/app_flowy/packages/flowy_editor/lib/service/default_text_operations/format_rich_text_style.dart

@@ -17,29 +17,38 @@ bool formatRichTextStyle(
   // 1. All nodes are text nodes.
   // 2. The first node is not TextNode.
   // 3. The last node is not TextNode.
-  for (var i = 0; i < textNodes.length; i++) {
-    final textNode = textNodes[i];
-    if (i == 0 && textNode == nodes.first) {
-      builder.formatText(
-        textNode,
-        selection.start.offset,
-        textNode.toRawString().length - selection.start.offset,
-        attributes,
-      );
-    } else if (i == textNodes.length - 1 && textNode == nodes.last) {
-      builder.formatText(
-        textNode,
-        0,
-        selection.end.offset,
-        attributes,
-      );
-    } else {
-      builder.formatText(
-        textNode,
-        0,
-        textNode.toRawString().length,
-        attributes,
-      );
+  if (nodes.length == textNodes.length && textNodes.length == 1) {
+    builder.formatText(
+      textNodes.first,
+      selection.start.offset,
+      selection.end.offset - selection.start.offset,
+      attributes,
+    );
+  } else {
+    for (var i = 0; i < textNodes.length; i++) {
+      final textNode = textNodes[i];
+      if (i == 0 && textNode == nodes.first) {
+        builder.formatText(
+          textNode,
+          selection.start.offset,
+          textNode.toRawString().length - selection.start.offset,
+          attributes,
+        );
+      } else if (i == textNodes.length - 1 && textNode == nodes.last) {
+        builder.formatText(
+          textNode,
+          0,
+          selection.end.offset,
+          attributes,
+        );
+      } else {
+        builder.formatText(
+          textNode,
+          0,
+          textNode.toRawString().length,
+          attributes,
+        );
+      }
     }
   }
 

+ 1 - 1
frontend/app_flowy/packages/flowy_editor/lib/service/toolbar_service.dart

@@ -35,7 +35,7 @@ class _FlowyToolbarState extends State<FlowyToolbar> with ToolbarService {
         editorState: widget.editorState,
         layerLink: layerLink,
         offset: offset.translate(0, -37.0),
-        handlers: const [],
+        handlers: const {},
       ),
     );
     Overlay.of(context)?.insert(_toolbarOverlay!);