Explorar el Código

fix: invalid drag start index

appflowy hace 2 años
padre
commit
a0d7f114c0

+ 7 - 13
frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/drag_state.dart

@@ -17,21 +17,18 @@ class FlexDragTargetData extends DragTargetData {
 
   Size? get feedbackSize => state.feedbackSize;
 
-  /// Indicate the dragTarget come from which [ReorderFlex].
-  final DraggingReorderFlex draggingReorderFlex;
-
   final String dragTargetId;
 
-  final ReoderFlexItem reorderFlexItem;
+  final String reorderFlexId;
 
-  String get reorderFlexId => draggingReorderFlex.reorderFlexId;
+  final ReoderFlexItem reorderFlexItem;
 
   FlexDragTargetData({
     required this.dragTargetId,
     required this.draggingIndex,
+    required this.reorderFlexId,
     required this.reorderFlexItem,
     required this.state,
-    required this.draggingReorderFlex,
   });
 
   @override
@@ -40,11 +37,6 @@ class FlexDragTargetData extends DragTargetData {
   }
 }
 
-abstract class DraggingReorderFlex {
-  String get reorderFlexId;
-  ReoderFlexItem itemAtIndex(int index);
-}
-
 class DraggingState {
   final String id;
 
@@ -85,10 +77,12 @@ class DraggingState {
     if (_draggingFeedbackSize == null) {
       return Size.zero;
     }
-    return _draggingFeedbackSize! + const Offset(_dropAreaMargin, _dropAreaMargin);
+    return _draggingFeedbackSize! +
+        const Offset(_dropAreaMargin, _dropAreaMargin);
   }
 
-  void startDragging(Widget draggingWidget, int draggingWidgetIndex, Size? draggingWidgetSize) {
+  void startDragging(Widget draggingWidget, int draggingWidgetIndex,
+      Size? draggingWidgetSize) {
     ///
     assert(draggingWidgetIndex >= 0);
 

+ 17 - 13
frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/drag_target_inteceptor.dart

@@ -25,7 +25,8 @@ abstract class ReorderFlexDragTargetInterceptor {
 
 abstract class OverlapReorderFlexDragTargetDelegate {}
 
-class OverlapReorderFlexDragTargetInteceptor extends ReorderFlexDragTargetInterceptor {
+class OverlapReorderFlexDragTargetInteceptor
+    extends ReorderFlexDragTargetInterceptor {
   final String reorderFlexId;
   final List<String> acceptedReorderFlexId;
   final OverlapReorderFlexDragTargetDelegate delegate;
@@ -49,7 +50,7 @@ class OverlapReorderFlexDragTargetInteceptor extends ReorderFlexDragTargetInterc
       required String dragTargetId,
       required int dragTargetIndex}) {
     if (dragTargetId == dragTargetData.reorderFlexId) {
-      Log.debug('remove all phantom');
+      // Log.debug('remove all phantom');
     }
 
     return true;
@@ -60,7 +61,7 @@ abstract class CrossReorderFlexDragTargetDelegate {
   bool acceptNewDragTargetData(
     String reorderFlexId,
     FlexDragTargetData dragTargetData,
-    int index,
+    int dragTargetIndex,
   );
 
   void updateDragTargetData(
@@ -70,7 +71,8 @@ abstract class CrossReorderFlexDragTargetDelegate {
   );
 }
 
-class CrossReorderFlexDragTargetInterceptor extends ReorderFlexDragTargetInterceptor {
+class CrossReorderFlexDragTargetInterceptor
+    extends ReorderFlexDragTargetInterceptor {
   final String reorderFlexId;
   final List<String> acceptedReorderFlexIds;
   final CrossReorderFlexDragTargetDelegate delegate;
@@ -102,21 +104,24 @@ class CrossReorderFlexDragTargetInterceptor extends ReorderFlexDragTargetInterce
 
   @override
   void onAccept(FlexDragTargetData dragTargetData) {
-    Log.trace('[$CrossReorderFlexDragTargetInterceptor] Column$reorderFlexId on onAccept');
+    Log.trace(
+        '[$CrossReorderFlexDragTargetInterceptor] Column$reorderFlexId on onAccept');
   }
 
   @override
   void onLeave(FlexDragTargetData dragTargetData) {
-    Log.trace('[$CrossReorderFlexDragTargetInterceptor] Column$reorderFlexId on leave');
+    Log.trace(
+        '[$CrossReorderFlexDragTargetInterceptor] Column$reorderFlexId on leave');
   }
 
   @override
-  bool onWillAccept(
-      {required BuildContext context,
-      required ReorderFlexState reorderFlexState,
-      required FlexDragTargetData dragTargetData,
-      required String dragTargetId,
-      required int dragTargetIndex}) {
+  bool onWillAccept({
+    required BuildContext context,
+    required ReorderFlexState reorderFlexState,
+    required FlexDragTargetData dragTargetData,
+    required String dragTargetId,
+    required int dragTargetIndex,
+  }) {
     final isNewDragTarget = delegate.acceptNewDragTargetData(
       reorderFlexId,
       dragTargetData,
@@ -132,7 +137,6 @@ class CrossReorderFlexDragTargetInterceptor extends ReorderFlexDragTargetInterce
 
       reorderFlexState.handleOnWillAccept(
         context,
-        dragTargetData.draggingIndex,
         dragTargetIndex,
       );
     }

+ 36 - 25
frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/reorder_flex.dart

@@ -13,7 +13,8 @@ typedef OnDragEnded = void Function();
 typedef OnReorder = void Function(int fromIndex, int toIndex);
 typedef OnDeleted = void Function(int deletedIndex);
 typedef OnInserted = void Function(int insertedIndex);
-typedef OnReveivePassedInPhantom = void Function(FlexDragTargetData dragTargetData, int phantomIndex);
+typedef OnReveivePassedInPhantom = void Function(
+    FlexDragTargetData dragTargetData, int phantomIndex);
 
 abstract class ReoderFlextDataSource {
   String get identifier;
@@ -32,7 +33,7 @@ class ReorderFlexConfig {
   const ReorderFlexConfig();
 }
 
-class ReorderFlex extends StatefulWidget with DraggingReorderFlex {
+class ReorderFlex extends StatefulWidget {
   final ReorderFlexConfig config;
 
   final List<Widget> children;
@@ -68,16 +69,11 @@ class ReorderFlex extends StatefulWidget with DraggingReorderFlex {
   @override
   State<ReorderFlex> createState() => ReorderFlexState();
 
-  @override
   String get reorderFlexId => dataSource.identifier;
-
-  @override
-  ReoderFlexItem itemAtIndex(int index) {
-    return dataSource.items[index];
-  }
 }
 
-class ReorderFlexState extends State<ReorderFlex> with ReorderFlexMinxi, TickerProviderStateMixin<ReorderFlex> {
+class ReorderFlexState extends State<ReorderFlex>
+    with ReorderFlexMinxi, TickerProviderStateMixin<ReorderFlex> {
   /// Controls scrolls and measures scroll progress.
   late ScrollController _scrollController;
   ScrollPosition? _attachedScrollPosition;
@@ -113,7 +109,9 @@ class ReorderFlexState extends State<ReorderFlex> with ReorderFlexMinxi, TickerP
       _attachedScrollPosition = null;
     }
 
-    _scrollController = widget.scrollController ?? PrimaryScrollController.of(context) ?? ScrollController();
+    _scrollController = widget.scrollController ??
+        PrimaryScrollController.of(context) ??
+        ScrollController();
 
     if (_scrollController.hasClients) {
       _attachedScrollPosition = Scrollable.of(context)?.position;
@@ -235,7 +233,9 @@ class ReorderFlexState extends State<ReorderFlex> with ReorderFlexMinxi, TickerP
             ]);
           } else if (childIndex == dragPhantomIndex) {
             return _buildDraggingContainer(
-                children: shiftedIndex <= childIndex ? [dragTarget, disappearSpace] : [disappearSpace, dragTarget]);
+                children: shiftedIndex <= childIndex
+                    ? [dragTarget, disappearSpace]
+                    : [disappearSpace, dragTarget]);
           }
         }
 
@@ -256,7 +256,9 @@ class ReorderFlexState extends State<ReorderFlex> with ReorderFlexMinxi, TickerP
             ]);
           } else if (childIndex == dragPhantomIndex) {
             return _buildDraggingContainer(
-                children: shiftedIndex >= childIndex ? [disappearSpace, dragTarget] : [dragTarget, disappearSpace]);
+                children: shiftedIndex >= childIndex
+                    ? [disappearSpace, dragTarget]
+                    : [dragTarget, disappearSpace]);
           }
         }
 
@@ -282,22 +284,25 @@ class ReorderFlexState extends State<ReorderFlex> with ReorderFlexMinxi, TickerP
     Widget child,
     int dragTargetIndex,
   ) {
-    final ReoderFlexItem reorderFlexItem = widget.dataSource.items[dragTargetIndex];
+    final ReoderFlexItem reorderFlexItem =
+        widget.dataSource.items[dragTargetIndex];
     return ReorderDragTarget<FlexDragTargetData>(
       dragTargetData: FlexDragTargetData(
         draggingIndex: dragTargetIndex,
+        reorderFlexId: widget.reorderFlexId,
         reorderFlexItem: reorderFlexItem,
         state: dragState,
-        draggingReorderFlex: widget,
         dragTargetId: reorderFlexItem.id,
       ),
       onDragStarted: (draggingWidget, draggingIndex, size) {
-        Log.debug("[DragTarget] Column${widget.dataSource.identifier} start dragging");
+        Log.debug(
+            "[DragTarget] Column${widget.dataSource.identifier} start dragging");
         _startDragging(draggingWidget, draggingIndex, size);
         widget.onDragStarted?.call(draggingIndex);
       },
       onDragEnded: (dragTargetData) {
-        Log.debug("[DragTarget]: Column${widget.dataSource.identifier} end dragging");
+        Log.debug(
+            "[DragTarget]: Column${widget.dataSource.identifier} end dragging");
 
         setState(() {
           _onReordered(
@@ -323,8 +328,7 @@ class ReorderFlexState extends State<ReorderFlex> with ReorderFlexMinxi, TickerP
         )) {
           return true;
         } else {
-          final dragIndex = dragTargetData.draggingIndex;
-          return handleOnWillAccept(builderContext, dragIndex, dragTargetIndex);
+          return handleOnWillAccept(builderContext, dragTargetIndex);
         }
       },
       onAccept: (dragTargetData) {
@@ -386,14 +390,17 @@ class ReorderFlexState extends State<ReorderFlex> with ReorderFlexMinxi, TickerP
     });
   }
 
-  bool handleOnWillAccept(BuildContext context, int? dragIndex, int dragTargetIndex) {
+  bool handleOnWillAccept(BuildContext context, int dragTargetIndex) {
+    final dragIndex = dragState.dragStartIndex;
+
     /// The [willAccept] will be true if the dargTarget is the widget that gets
     /// dragged and it is dragged on top of the other dragTargets.
     ///
     Log.debug(
         '[$ReorderDragTarget] ${widget.dataSource.identifier} on will accept, dragIndex:$dragIndex, dragTargetIndex:$dragTargetIndex, count: ${widget.dataSource.items.length}');
 
-    bool willAccept = dragState.dragStartIndex == dragIndex && dragIndex != dragTargetIndex;
+    bool willAccept =
+        dragState.dragStartIndex == dragIndex && dragIndex != dragTargetIndex;
     setState(() {
       if (willAccept) {
         int shiftedIndex = dragState.calculateShiftedIndex(dragTargetIndex);
@@ -420,7 +427,8 @@ class ReorderFlexState extends State<ReorderFlex> with ReorderFlexMinxi, TickerP
   }
 
   Widget _wrapScrollView({required Widget child}) {
-    if (widget.scrollController != null && PrimaryScrollController.of(context) == null) {
+    if (widget.scrollController != null &&
+        PrimaryScrollController.of(context) == null) {
       return child;
     } else {
       return SingleChildScrollView(
@@ -474,12 +482,14 @@ class ReorderFlexState extends State<ReorderFlex> with ReorderFlexMinxi, TickerP
   void _scrollTo(BuildContext context) {
     if (_scrolling) return;
     final RenderObject contextObject = context.findRenderObject()!;
-    final RenderAbstractViewport viewport = RenderAbstractViewport.of(contextObject)!;
+    final RenderAbstractViewport viewport =
+        RenderAbstractViewport.of(contextObject)!;
     // If and only if the current scroll offset falls in-between the offsets
     // necessary to reveal the selected context at the top or bottom of the
     // screen, then it is already on-screen.
-    final double margin =
-        widget.direction == Axis.horizontal ? dragState.dropAreaSize.width : dragState.dropAreaSize.height;
+    final double margin = widget.direction == Axis.horizontal
+        ? dragState.dropAreaSize.width
+        : dragState.dropAreaSize.height;
     if (_scrollController.hasClients) {
       final double scrollOffset = _scrollController.offset;
       final double topOffset = max(
@@ -490,7 +500,8 @@ class ReorderFlexState extends State<ReorderFlex> with ReorderFlexMinxi, TickerP
         _scrollController.position.maxScrollExtent,
         viewport.getOffsetToReveal(contextObject, 1.0).offset + margin,
       );
-      final bool onScreen = scrollOffset <= topOffset && scrollOffset >= bottomOffset;
+      final bool onScreen =
+          scrollOffset <= topOffset && scrollOffset >= bottomOffset;
 
       // If the context is off screen, then we request a scroll to make it visible.
       if (!onScreen) {

+ 48 - 23
frontend/app_flowy/packages/flowy_board/lib/src/widgets/phantom/phantom_controller.dart

@@ -1,5 +1,4 @@
 import 'package:flutter/material.dart';
-import 'package:flutter/scheduler.dart';
 import '../../../flowy_board.dart';
 import '../../utils/log.dart';
 import '../flex/drag_state.dart';
@@ -15,7 +14,8 @@ mixin ColumnDataPhantomMixim {
   BoardColumnDataController? get;
 }
 
-class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate with CrossReorderFlexDragTargetDelegate {
+class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate
+    with CrossReorderFlexDragTargetDelegate {
   final BoardPhantomControllerDelegate delegate;
 
   PhantomRecord? phantomRecord;
@@ -64,10 +64,16 @@ class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate with C
     if (columnsState.isDragging(phantomRecord!.fromColumnId) == false) {
       return;
     }
-    final item = delegate.controller(phantomRecord!.fromColumnId)?.removeAt(phantomRecord!.fromColumnIndex);
+    final item = delegate
+        .controller(phantomRecord!.fromColumnId)
+        ?.removeAt(phantomRecord!.fromColumnIndex);
     assert(item != null);
-    assert(delegate.controller(phantomRecord!.toColumnId)?.items[phantomRecord!.toColumnIndex] is PhantomColumnItem);
-    delegate.controller(phantomRecord!.toColumnId)?.replace(phantomRecord!.toColumnIndex, item!);
+    assert(delegate
+        .controller(phantomRecord!.toColumnId)
+        ?.items[phantomRecord!.toColumnIndex] is PhantomColumnItem);
+    delegate
+        .controller(phantomRecord!.toColumnId)
+        ?.replace(phantomRecord!.toColumnIndex, item!);
 
     Log.debug("[$BoardPhantomController] did move ${phantomRecord.toString()}");
     phantomRecord = null;
@@ -76,24 +82,28 @@ class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate with C
   void _updatePhantom(
     String toColumnId,
     FlexDragTargetData dragTargetData,
-    int phantomIndex,
+    int dragTargetIndex,
   ) {
     final columnDataController = delegate.controller(toColumnId);
-    final index = columnDataController?.items.indexWhere((item) => item.isPhantom);
+    final index =
+        columnDataController?.items.indexWhere((item) => item.isPhantom);
     if (index == null) return;
 
     assert(index != -1);
     if (index != -1) {
-      if (index != phantomIndex) {
+      if (index != dragTargetIndex) {
         // Log.debug('[$BoardPhantomController] update $toColumnId:$index to $toColumnId:$phantomIndex');
         final item = columnDataController!.removeAt(index, notify: false);
-        columnDataController.insert(phantomIndex, item, notify: false);
+        columnDataController.insert(dragTargetIndex, item, notify: false);
       }
     }
   }
 
   void _removePhantom(String columnId) {
-    final index = delegate.controller(columnId)?.items.indexWhere((item) => item.isPhantom);
+    final index = delegate
+        .controller(columnId)
+        ?.items
+        .indexWhere((item) => item.isPhantom);
 
     if (index == null) return;
 
@@ -124,7 +134,9 @@ class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate with C
     );
     columnsState.addColumnListener(toColumnId, phantomContext);
     Log.debug('$phantomContext');
-    delegate.controller(toColumnId)?.insert(phantomIndex, PhantomColumnItem(phantomContext));
+    delegate
+        .controller(toColumnId)
+        ?.insert(phantomIndex, PhantomColumnItem(phantomContext));
 
     WidgetsBinding.instance.addPostFrameCallback((_) {
       Future.delayed(const Duration(milliseconds: 100), () {
@@ -152,10 +164,14 @@ class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate with C
   }
 
   @override
-  bool acceptNewDragTargetData(String reorderFlexId, FlexDragTargetData dragTargetData, int index) {
+  bool acceptNewDragTargetData(
+    String reorderFlexId,
+    FlexDragTargetData dragTargetData,
+    int dragTargetIndex,
+  ) {
     if (phantomRecord == null) {
-      _updatePhantomRecord(reorderFlexId, dragTargetData, index);
-      _insertPhantom(reorderFlexId, dragTargetData, index);
+      _updatePhantomRecord(reorderFlexId, dragTargetData, dragTargetIndex);
+      _insertPhantom(reorderFlexId, dragTargetData, dragTargetIndex);
       return false;
     }
 
@@ -165,21 +181,26 @@ class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate with C
       _removePhantom(phantomRecord!.toColumnId);
 
       /// Update the record and insert the phantom to new column.
-      _updatePhantomRecord(reorderFlexId, dragTargetData, index);
-      _insertPhantom(reorderFlexId, dragTargetData, index);
+      _updatePhantomRecord(reorderFlexId, dragTargetData, dragTargetIndex);
+      _insertPhantom(reorderFlexId, dragTargetData, dragTargetIndex);
     }
 
     return isNewDragTarget;
   }
 
   @override
-  void updateDragTargetData(String reorderFlexId, FlexDragTargetData dragTargetData, int dragTargetIndex) {
+  void updateDragTargetData(
+    String reorderFlexId,
+    FlexDragTargetData dragTargetData,
+    int dragTargetIndex,
+  ) {
     phantomRecord?.updateInsertedIndex(dragTargetIndex);
 
     assert(phantomRecord != null);
     if (phantomRecord!.toColumnId == reorderFlexId) {
       /// Update the existing phantom index
-      _updatePhantom(phantomRecord!.toColumnId, dragTargetData, dragTargetIndex);
+      _updatePhantom(
+          phantomRecord!.toColumnId, dragTargetData, dragTargetIndex);
     }
   }
 }
@@ -204,7 +225,8 @@ class PhantomRecord {
     if (fromColumnIndex == index) {
       return;
     }
-    Log.debug('[$PhantomRecord] Update Column$fromColumnId remove position to $index');
+    Log.debug(
+        '[$PhantomRecord] Update Column$fromColumnId remove position to $index');
     fromColumnIndex = index;
   }
 
@@ -213,7 +235,8 @@ class PhantomRecord {
       return;
     }
 
-    Log.debug('[$PhantomRecord] Column$toColumnId update position $toColumnIndex -> $index');
+    Log.debug(
+        '[$PhantomRecord] Column$toColumnId update position $toColumnIndex -> $index');
     toColumnIndex = index;
   }
 
@@ -226,7 +249,8 @@ class PhantomRecord {
 class PhantomColumnItem extends ColumnItem {
   final PassthroughPhantomContext phantomContext;
 
-  PhantomColumnItem(PassthroughPhantomContext insertedPhantom) : phantomContext = insertedPhantom;
+  PhantomColumnItem(PassthroughPhantomContext insertedPhantom)
+      : phantomContext = insertedPhantom;
 
   @override
   bool get isPhantom => true;
@@ -236,8 +260,9 @@ class PhantomColumnItem extends ColumnItem {
 
   Size? get feedbackSize => phantomContext.feedbackSize;
 
-  Widget get draggingWidget =>
-      phantomContext.draggingWidget == null ? const SizedBox() : phantomContext.draggingWidget!;
+  Widget get draggingWidget => phantomContext.draggingWidget == null
+      ? const SizedBox()
+      : phantomContext.draggingWidget!;
 }
 
 class PassthroughPhantomContext extends FakeDragTargetEventTrigger