Explorar o código

feat: refactor current selection and current selectedNodes in selection_service

Lucas.Xu %!s(int64=2) %!d(string=hai) anos
pai
achega
7e6c7a2b4e

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

@@ -67,13 +67,13 @@ class _ToolbarWidgetState extends State<ToolbarWidget> {
   void initState() {
     super.initState();
 
-    widget.editorState.service.selectionService.currentSelectedNodes
+    widget.editorState.service.selectionService.currentSelection
         .addListener(_onSelectionChange);
   }
 
   @override
   void dispose() {
-    widget.editorState.service.selectionService.currentSelectedNodes
+    widget.editorState.service.selectionService.currentSelection
         .removeListener(_onSelectionChange);
     super.dispose();
   }

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

@@ -38,7 +38,7 @@ void formatBulletedList(EditorState editorState) {
 }
 
 bool formatTextNodes(EditorState editorState, Attributes attributes) {
-  final nodes = editorState.service.selectionService.currentSelectedNodes.value;
+  final nodes = editorState.service.selectionService.currentSelectedNodes;
   final textNodes = nodes.whereType<TextNode>().toList();
 
   if (textNodes.isEmpty) {
@@ -85,8 +85,8 @@ bool formatStrikethrough(EditorState editorState) {
 }
 
 bool formatRichTextPartialStyle(EditorState editorState, String styleKey) {
-  final selection = editorState.service.selectionService.currentSelection;
-  final nodes = editorState.service.selectionService.currentSelectedNodes.value;
+  final selection = editorState.service.selectionService.currentSelection.value;
+  final nodes = editorState.service.selectionService.currentSelectedNodes;
   final textNodes = nodes.whereType<TextNode>().toList(growable: false);
 
   if (selection == null || textNodes.isEmpty) {
@@ -107,8 +107,8 @@ bool formatRichTextPartialStyle(EditorState editorState, String styleKey) {
 }
 
 bool formatRichTextStyle(EditorState editorState, Attributes attributes) {
-  final selection = editorState.service.selectionService.currentSelection;
-  final nodes = editorState.service.selectionService.currentSelectedNodes.value;
+  final selection = editorState.service.selectionService.currentSelection.value;
+  final nodes = editorState.service.selectionService.currentSelectedNodes;
   final textNodes = nodes.whereType<TextNode>().toList();
 
   if (selection == null || textNodes.isEmpty) {

+ 12 - 14
frontend/app_flowy/packages/flowy_editor/lib/service/input_service.dart

@@ -42,15 +42,15 @@ class _FlowyInputState extends State<FlowyInput>
   void initState() {
     super.initState();
 
-    _editorState.service.selectionService.currentSelectedNodes
-        .addListener(_onSelectedNodesChange);
+    _editorState.service.selectionService.currentSelection
+        .addListener(_onSelectionChange);
   }
 
   @override
   void dispose() {
     close();
-    _editorState.service.selectionService.currentSelectedNodes
-        .removeListener(_onSelectedNodesChange);
+    _editorState.service.selectionService.currentSelection
+        .removeListener(_onSelectionChange);
 
     super.dispose();
   }
@@ -105,13 +105,12 @@ class _FlowyInputState extends State<FlowyInput>
 
   void _applyInsert(TextEditingDeltaInsertion delta) {
     final selectionService = _editorState.service.selectionService;
-    final currentSelection = selectionService.currentSelection;
+    final currentSelection = selectionService.currentSelection.value;
     if (currentSelection == null) {
       return;
     }
     if (currentSelection.isSingle) {
-      final textNode =
-          selectionService.currentSelectedNodes.value.first as TextNode;
+      final textNode = selectionService.currentSelectedNodes.first as TextNode;
       TransactionBuilder(_editorState)
         ..insertText(
           textNode,
@@ -126,13 +125,12 @@ class _FlowyInputState extends State<FlowyInput>
 
   void _applyReplacement(TextEditingDeltaReplacement delta) {
     final selectionService = _editorState.service.selectionService;
-    final currentSelection = selectionService.currentSelection;
+    final currentSelection = selectionService.currentSelection.value;
     if (currentSelection == null) {
       return;
     }
     if (currentSelection.isSingle) {
-      final textNode =
-          selectionService.currentSelectedNodes.value.first as TextNode;
+      final textNode = selectionService.currentSelectedNodes.first as TextNode;
       final length = delta.replacedRange.end - delta.replacedRange.start;
       TransactionBuilder(_editorState)
         ..replaceText(
@@ -209,11 +207,11 @@ class _FlowyInputState extends State<FlowyInput>
     // TODO: implement updateFloatingCursor
   }
 
-  void _onSelectedNodesChange() {
-    final textNodes = _editorState
-        .service.selectionService.currentSelectedNodes.value
+  void _onSelectionChange() {
+    final textNodes = _editorState.service.selectionService.currentSelectedNodes
         .whereType<TextNode>();
-    final selection = _editorState.service.selectionService.currentSelection;
+    final selection =
+        _editorState.service.selectionService.currentSelection.value;
     // FIXME: upward and selection update.
     if (textNodes.isNotEmpty && selection != null) {
       final text = textNodes.fold<String>(

+ 2 - 2
frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/delete_text_handler.dart

@@ -9,12 +9,12 @@ FlowyKeyEventHandler deleteTextHandler = (editorState, event) {
     return KeyEventResult.ignored;
   }
 
-  final selection = editorState.service.selectionService.currentSelection;
+  final selection = editorState.service.selectionService.currentSelection.value;
   if (selection == null) {
     return KeyEventResult.ignored;
   }
 
-  final nodes = editorState.service.selectionService.currentSelectedNodes.value;
+  final nodes = editorState.service.selectionService.currentSelectedNodes;
   // make sure all nodes is [TextNode].
   final textNodes = nodes.whereType<TextNode>().toList();
   if (textNodes.length != nodes.length) {

+ 2 - 2
frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/enter_in_edge_of_text_node_handler.dart

@@ -18,8 +18,8 @@ FlowyKeyEventHandler enterInEdgeOfTextNodeHandler = (editorState, event) {
     return KeyEventResult.ignored;
   }
 
-  final nodes = editorState.service.selectionService.currentSelectedNodes.value;
-  final selection = editorState.service.selectionService.currentSelection;
+  final nodes = editorState.service.selectionService.currentSelectedNodes;
+  final selection = editorState.service.selectionService.currentSelection.value;
   if (selection == null ||
       nodes.length != 1 ||
       nodes.first is! TextNode ||

+ 4 - 5
frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/slash_handler.dart

@@ -56,14 +56,13 @@ FlowyKeyEventHandler slashShortcutHandler = (editorState, event) {
     return KeyEventResult.ignored;
   }
 
-  final textNodes = editorState
-      .service.selectionService.currentSelectedNodes.value
+  final textNodes = editorState.service.selectionService.currentSelectedNodes
       .whereType<TextNode>();
   if (textNodes.length != 1) {
     return KeyEventResult.ignored;
   }
 
-  final selection = editorState.service.selectionService.currentSelection;
+  final selection = editorState.service.selectionService.currentSelection.value;
   final textNode = textNodes.first;
   final context = textNode.context;
   final selectable = textNode.selectable;
@@ -97,9 +96,9 @@ FlowyKeyEventHandler slashShortcutHandler = (editorState, event) {
 
   Overlay.of(context)?.insert(_popupListOverlay!);
 
-  editorState.service.selectionService.currentSelectedNodes
+  editorState.service.selectionService.currentSelection
       .removeListener(clearPopupListOverlay);
-  editorState.service.selectionService.currentSelectedNodes
+  editorState.service.selectionService.currentSelection
       .addListener(clearPopupListOverlay);
   // editorState.service.keyboardService?.disable();
   _editorState = editorState;

+ 2 - 2
frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/update_text_style_by_command_x_handler.dart

@@ -9,8 +9,8 @@ FlowyKeyEventHandler updateTextStyleByCommandXHandler = (editorState, event) {
     return KeyEventResult.ignored;
   }
 
-  final selection = editorState.service.selectionService.currentSelection;
-  final nodes = editorState.service.selectionService.currentSelectedNodes.value;
+  final selection = editorState.service.selectionService.currentSelection.value;
+  final nodes = editorState.service.selectionService.currentSelectedNodes;
   final textNodes = nodes.whereType<TextNode>().toList(growable: false);
 
   if (selection == null || textNodes.isEmpty) {

+ 22 - 16
frontend/app_flowy/packages/flowy_editor/lib/service/selection_service.dart

@@ -17,20 +17,26 @@ import 'package:flowy_editor/render/selection/selection_widget.dart';
 
 /// Process selection and cursor
 mixin FlowySelectionService<T extends StatefulWidget> on State<T> {
-  /// Returns the currently selected [Node]s.
+  /// Returns the current [Selection]
+  ValueNotifier<Selection?> get currentSelection;
+
+  /// Returns the current selected [Node]s.
   ///
   /// The order of the return is determined according to the selected order.
-  ValueNotifier<List<Node>> get currentSelectedNodes;
-  Selection? get currentSelection;
-
-  /// ------------------ Selection ------------------------
+  List<Node> get currentSelectedNodes;
 
+  /// Update the selection or cursor.
   ///
+  /// If selection is collapsed, this method will
+  ///   update the position of the cursor.
+  /// Otherwise, will update the selection.
   void updateSelection(Selection selection);
 
-  ///
+  /// Clear the selection or cursor.
   void clearSelection();
 
+  /// ------------------ Selection ------------------------
+
   List<Rect> rects();
 
   Position? hitTest(Offset? offset);
@@ -124,10 +130,10 @@ class _FlowySelectionState extends State<FlowySelection>
   EditorState get editorState => widget.editorState;
 
   @override
-  Selection? currentSelection;
+  ValueNotifier<Selection?> currentSelection = ValueNotifier(null);
 
   @override
-  ValueNotifier<List<Node>> currentSelectedNodes = ValueNotifier([]);
+  List<Node> currentSelectedNodes = [];
 
   @override
   List<Node> getNodesInSelection(Selection selection) =>
@@ -145,8 +151,8 @@ class _FlowySelectionState extends State<FlowySelection>
     super.didChangeMetrics();
 
     // Need to refresh the selection when the metrics changed.
-    if (currentSelection != null) {
-      updateSelection(currentSelection!);
+    if (currentSelection.value != null) {
+      updateSelection(currentSelection.value!);
     }
   }
 
@@ -192,8 +198,8 @@ class _FlowySelectionState extends State<FlowySelection>
 
   @override
   void clearSelection() {
-    currentSelection = null;
-    currentSelectedNodes.value = [];
+    currentSelectedNodes = [];
+    currentSelection.value = null;
 
     // clear selection
     _selectionOverlays
@@ -399,8 +405,8 @@ class _FlowySelectionState extends State<FlowySelection>
   void _updateSelection(Selection selection) {
     final nodes = _selectedNodesInSelection(editorState.document, selection);
 
-    currentSelection = selection;
-    currentSelectedNodes.value = nodes;
+    currentSelectedNodes = nodes;
+    currentSelection.value = selection;
 
     Rect? topmostRect;
     LayerLink? layerLink;
@@ -480,8 +486,8 @@ class _FlowySelectionState extends State<FlowySelection>
       return;
     }
 
-    currentSelection = Selection.collapsed(position);
-    currentSelectedNodes.value = [node];
+    currentSelectedNodes = [node];
+    currentSelection.value = Selection.collapsed(position);
 
     final selectable = node.selectable;
     final rect = selectable?.getCursorRectInPosition(position);