소스 검색

fix: fix some bugs

appflowy 2 년 전
부모
커밋
146cc5c5e9

+ 2 - 4
frontend/app_flowy/packages/flowy_board/lib/src/widgets/board.dart

@@ -122,16 +122,14 @@ class BoardContent extends StatefulWidget {
 }
 
 class _BoardContentState extends State<BoardContent> {
-  final GlobalKey _columnContainerOverlayKey =
-      GlobalKey(debugLabel: '$BoardContent overlay key');
+  final GlobalKey _columnContainerOverlayKey = GlobalKey(debugLabel: '$BoardContent overlay key');
   late BoardOverlayEntry _overlayEntry;
 
   @override
   void initState() {
     _overlayEntry = BoardOverlayEntry(
       builder: (BuildContext context) {
-        List<Widget> children =
-            widget.dataController.columnDatas.map((columnData) {
+        List<Widget> children = widget.dataController.columnDatas.map((columnData) {
           return _buildColumn(
             columnData.id,
             widget.dataController.columnIds,

+ 26 - 21
frontend/app_flowy/packages/flowy_board/lib/src/widgets/board_column/data_controller.dart

@@ -1,3 +1,5 @@
+import 'dart:collection';
+
 import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
 import '../../utils/log.dart';
@@ -8,22 +10,26 @@ abstract class ColumnItem extends ReoderFlexItem {
 
   @override
   String toString() {
-    return id;
+    if (isPhantom) {
+      return 'phantom:$id';
+    } else {
+      return id;
+    }
   }
 }
 
 class BoardColumnData extends ReoderFlexItem with EquatableMixin {
   @override
   final String id;
-  final List<ColumnItem> items;
+  final List<ColumnItem> _items;
 
   BoardColumnData({
     required this.id,
-    required this.items,
-  });
+    required List<ColumnItem> items,
+  }) : _items = items;
 
   @override
-  List<Object?> get props => [id, ...items];
+  List<Object?> get props => [id, ..._items];
 
   @override
   String toString() {
@@ -31,8 +37,7 @@ class BoardColumnData extends ReoderFlexItem with EquatableMixin {
   }
 }
 
-class BoardColumnDataController extends ChangeNotifier
-    with EquatableMixin, ReoderFlextDataSource {
+class BoardColumnDataController extends ChangeNotifier with EquatableMixin, ReoderFlextDataSource {
   final BoardColumnData columnData;
 
   BoardColumnDataController({
@@ -42,10 +47,12 @@ class BoardColumnDataController extends ChangeNotifier
   @override
   List<Object?> get props => columnData.props;
 
-  ColumnItem removeAt(int index) {
+  ColumnItem removeAt(int index, {bool notify = true}) {
     Log.debug('[$BoardColumnDataController] $columnData remove item at $index');
-    final item = columnData.items.removeAt(index);
-    notifyListeners();
+    final item = columnData._items.removeAt(index);
+    if (notify) {
+      notifyListeners();
+    }
     return item;
   }
 
@@ -53,31 +60,29 @@ class BoardColumnDataController extends ChangeNotifier
     if (fromIndex == toIndex) {
       return;
     }
-    Log.debug(
-        '[$BoardColumnDataController] $columnData move item from $fromIndex to $toIndex');
-    final item = columnData.items.removeAt(fromIndex);
-    columnData.items.insert(toIndex, item);
+    Log.debug('[$BoardColumnDataController] $columnData move item from $fromIndex to $toIndex');
+    final item = columnData._items.removeAt(fromIndex);
+    columnData._items.insert(toIndex, item);
     notifyListeners();
   }
 
   void insert(int index, ColumnItem item, {bool notify = true}) {
-    Log.debug('[$BoardColumnDataController] $columnData insert item at $index');
-    columnData.items.insert(index, item);
+    Log.debug('[$BoardColumnDataController] $columnData insert $item at $index');
+    columnData._items.insert(index, item);
     if (notify) {
       notifyListeners();
     }
   }
 
   void replace(int index, ColumnItem item) {
-    Log.debug(
-        '[$BoardColumnDataController] $columnData replace item at $index');
-    columnData.items.removeAt(index);
-    columnData.items.insert(index, item);
+    final removedItem = columnData._items.removeAt(index);
+    columnData._items.insert(index, item);
+    Log.debug('[$BoardColumnDataController] $columnData replace $removedItem with $item at $index');
     notifyListeners();
   }
 
   @override
-  List<ColumnItem> get items => columnData.items;
+  List<ColumnItem> get items => UnmodifiableListView(columnData._items);
 
   @override
   String get identifier => columnData.id;

+ 4 - 6
frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/drag_state.dart

@@ -22,14 +22,14 @@ class FlexDragTargetData extends DragTargetData {
 
   final String dragTargetId;
 
-  ReoderFlexItem get reorderFlexItem =>
-      draggingReorderFlex.itemAtIndex(draggingIndex);
+  final ReoderFlexItem reorderFlexItem;
 
   String get reorderFlexId => draggingReorderFlex.reorderFlexId;
 
   FlexDragTargetData({
     required this.dragTargetId,
     required this.draggingIndex,
+    required this.reorderFlexItem,
     required this.state,
     required this.draggingReorderFlex,
   });
@@ -85,12 +85,10 @@ 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);
 

+ 5 - 9
frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/drag_target_inteceptor.dart

@@ -25,8 +25,7 @@ abstract class ReorderFlexDragTargetInterceptor {
 
 abstract class OverlapReorderFlexDragTargetDelegate {}
 
-class OverlapReorderFlexDragTargetInteceptor
-    extends ReorderFlexDragTargetInterceptor {
+class OverlapReorderFlexDragTargetInteceptor extends ReorderFlexDragTargetInterceptor {
   final String reorderFlexId;
   final List<String> acceptedReorderFlexId;
   final OverlapReorderFlexDragTargetDelegate delegate;
@@ -71,8 +70,7 @@ abstract class CrossReorderFlexDragTargetDelegate {
   );
 }
 
-class CrossReorderFlexDragTargetInterceptor
-    extends ReorderFlexDragTargetInterceptor {
+class CrossReorderFlexDragTargetInterceptor extends ReorderFlexDragTargetInterceptor {
   final String reorderFlexId;
   final List<String> acceptedReorderFlexIds;
   final CrossReorderFlexDragTargetDelegate delegate;
@@ -104,14 +102,12 @@ class CrossReorderFlexDragTargetInterceptor
 
   @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
@@ -134,7 +130,7 @@ class CrossReorderFlexDragTargetInterceptor
         dragTargetIndex,
       );
 
-      reorderFlexState.onWillAccept(
+      reorderFlexState.handleOnWillAccept(
         context,
         dragTargetData.draggingIndex,
         dragTargetIndex,

+ 24 - 33
frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/reorder_flex.dart

@@ -13,8 +13,7 @@ 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;
@@ -78,8 +77,7 @@ class ReorderFlex extends StatefulWidget with DraggingReorderFlex {
   }
 }
 
-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;
@@ -115,9 +113,7 @@ class ReorderFlexState extends State<ReorderFlex>
       _attachedScrollPosition = null;
     }
 
-    _scrollController = widget.scrollController ??
-        PrimaryScrollController.of(context) ??
-        ScrollController();
+    _scrollController = widget.scrollController ?? PrimaryScrollController.of(context) ?? ScrollController();
 
     if (_scrollController.hasClients) {
       _attachedScrollPosition = Scrollable.of(context)?.position;
@@ -239,9 +235,7 @@ class ReorderFlexState extends State<ReorderFlex>
             ]);
           } else if (childIndex == dragPhantomIndex) {
             return _buildDraggingContainer(
-                children: shiftedIndex <= childIndex
-                    ? [dragTarget, disappearSpace]
-                    : [disappearSpace, dragTarget]);
+                children: shiftedIndex <= childIndex ? [dragTarget, disappearSpace] : [disappearSpace, dragTarget]);
           }
         }
 
@@ -262,9 +256,7 @@ class ReorderFlexState extends State<ReorderFlex>
             ]);
           } else if (childIndex == dragPhantomIndex) {
             return _buildDraggingContainer(
-                children: shiftedIndex >= childIndex
-                    ? [disappearSpace, dragTarget]
-                    : [dragTarget, disappearSpace]);
+                children: shiftedIndex >= childIndex ? [disappearSpace, dragTarget] : [dragTarget, disappearSpace]);
           }
         }
 
@@ -290,21 +282,22 @@ class ReorderFlexState extends State<ReorderFlex>
     Widget child,
     int dragTargetIndex,
   ) {
-    final ReoderFlexItem item = widget.dataSource.items[dragTargetIndex];
+    final ReoderFlexItem reorderFlexItem = widget.dataSource.items[dragTargetIndex];
     return ReorderDragTarget<FlexDragTargetData>(
       dragTargetData: FlexDragTargetData(
         draggingIndex: dragTargetIndex,
+        reorderFlexItem: reorderFlexItem,
         state: dragState,
         draggingReorderFlex: widget,
-        dragTargetId: item.id,
+        dragTargetId: reorderFlexItem.id,
       ),
       onDragStarted: (draggingWidget, draggingIndex, size) {
-        Log.debug("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("Column${widget.dataSource.identifier} end dragging");
+        Log.debug("[DragTarget]: Column${widget.dataSource.identifier} end dragging");
 
         setState(() {
           _onReordered(
@@ -317,22 +310,21 @@ class ReorderFlexState extends State<ReorderFlex>
       },
       onWillAccept: (FlexDragTargetData dragTargetData) {
         assert(widget.dataSource.items.length > dragTargetIndex);
-        Log.debug(
-            '[$ReorderDragTarget] ${widget.dataSource.identifier} on will accept, count: ${widget.dataSource.items.length}');
+
         if (_interceptDragTarget(
           dragTargetData,
           (interceptor) => interceptor.onWillAccept(
             context: builderContext,
             reorderFlexState: this,
             dragTargetData: dragTargetData,
-            dragTargetId: item.id,
+            dragTargetId: reorderFlexItem.id,
             dragTargetIndex: dragTargetIndex,
           ),
         )) {
           return true;
         } else {
           final dragIndex = dragTargetData.draggingIndex;
-          return onWillAccept(builderContext, dragIndex, dragTargetIndex);
+          return handleOnWillAccept(builderContext, dragIndex, dragTargetIndex);
         }
       },
       onAccept: (dragTargetData) {
@@ -394,11 +386,14 @@ class ReorderFlexState extends State<ReorderFlex>
     });
   }
 
-  bool onWillAccept(BuildContext context, int? dragIndex, int childIndex) {
+  bool handleOnWillAccept(BuildContext context, int? dragIndex, int childIndex) {
     /// The [willAccept] will be true if the dargTarget is the widget that gets
     /// dragged and it is dragged on top of the other dragTargets.
-    bool willAccept =
-        dragState.dragStartIndex == dragIndex && dragIndex != childIndex;
+    ///
+    Log.trace(
+        '[$ReorderDragTarget] ${widget.dataSource.identifier} on will accept, count: ${widget.dataSource.items.length}');
+
+    bool willAccept = dragState.dragStartIndex == dragIndex && dragIndex != childIndex;
     setState(() {
       if (willAccept) {
         int shiftedIndex = dragState.calculateShiftedIndex(childIndex);
@@ -425,8 +420,7 @@ class ReorderFlexState extends State<ReorderFlex>
   }
 
   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(
@@ -480,14 +474,12 @@ class ReorderFlexState extends State<ReorderFlex>
   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(
@@ -498,8 +490,7 @@ class ReorderFlexState extends State<ReorderFlex>
         _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) {

+ 26 - 57
frontend/app_flowy/packages/flowy_board/lib/src/widgets/phantom/phantom_controller.dart

@@ -14,8 +14,7 @@ mixin ColumnDataPhantomMixim {
   BoardColumnDataController? get;
 }
 
-class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate
-    with CrossReorderFlexDragTargetDelegate {
+class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate with CrossReorderFlexDragTargetDelegate {
   final BoardPhantomControllerDelegate delegate;
 
   PhantomRecord? phantomRecord;
@@ -64,22 +63,12 @@ class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate
     if (columnsState.isDragging(phantomRecord!.fromColumnId) == false) {
       return;
     }
-
-    Log.debug("[$BoardPhantomController] move ${phantomRecord.toString()}");
-
-    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;
   }
 
@@ -88,28 +77,22 @@ class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate
     FlexDragTargetData dragTargetData,
     int phantomIndex,
   ) {
-    final items = delegate.controller(toColumnId)?.items;
-    if (items == null) {
-      return;
-    }
+    final columnDataController = delegate.controller(toColumnId);
+    final index = columnDataController?.items.indexWhere((item) => item.isPhantom);
+    if (index == null) return;
 
-    final index = items.indexWhere((item) => item.isPhantom);
     assert(index != -1);
     if (index != -1) {
       if (index != phantomIndex) {
-        Log.debug(
-            '[$BoardPhantomController] move phantom $toColumnId:$index to $toColumnId:$phantomIndex');
-        final item = items.removeAt(index);
-        items.insert(phantomIndex, item);
+        // Log.debug('[$BoardPhantomController] update $toColumnId:$index to $toColumnId:$phantomIndex');
+        final item = columnDataController!.removeAt(index, notify: false);
+        columnDataController.insert(phantomIndex, 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;
 
@@ -139,15 +122,11 @@ class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate
       dragTargetData: dragTargetData,
     );
     columnsState.addColumnListener(toColumnId, phantomContext);
-
-    Log.debug(
-        '[$BoardPhantomController] Column$toColumnId insert phantom at $phantomIndex');
-    delegate
-        .controller(toColumnId)
-        ?.insert(phantomIndex, PhantomColumnItem(phantomContext));
+    Log.debug('$phantomContext');
+    delegate.controller(toColumnId)?.insert(phantomIndex, PhantomColumnItem(phantomContext));
 
     WidgetsBinding.instance.addPostFrameCallback((_) {
-      Future.delayed(const Duration(microseconds: 100), () {
+      Future.delayed(const Duration(milliseconds: 00), () {
         columnsState.notifyDidInsertPhantom(toColumnId);
       });
     });
@@ -158,9 +137,8 @@ class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate
     FlexDragTargetData dragTargetData,
     int index,
   ) {
-    Log.debug(
-        '[$BoardPhantomController] move Column${dragTargetData.reorderFlexId}:${dragTargetData.draggingIndex} '
-        'to Column$columnId:$index');
+    // Log.debug('[$BoardPhantomController] move Column${dragTargetData.reorderFlexId}:${dragTargetData.draggingIndex} '
+    //     'to Column$columnId:$index');
 
     phantomRecord = PhantomRecord(
       toColumnId: columnId,
@@ -169,11 +147,11 @@ class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate
       fromColumnId: dragTargetData.reorderFlexId,
       fromColumnIndex: dragTargetData.draggingIndex,
     );
+    Log.debug('[$BoardPhantomController] will move: $phantomRecord');
   }
 
   @override
-  bool acceptNewDragTargetData(
-      String reorderFlexId, FlexDragTargetData dragTargetData, int index) {
+  bool acceptNewDragTargetData(String reorderFlexId, FlexDragTargetData dragTargetData, int index) {
     if (phantomRecord == null) {
       _updatePhantomRecord(reorderFlexId, dragTargetData, index);
       _insertPhantom(reorderFlexId, dragTargetData, index);
@@ -181,8 +159,6 @@ class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate
     }
 
     final isNewDragTarget = phantomRecord!.toColumnId != reorderFlexId;
-    Log.debug(
-        '[$BoardPhantomController] Set inserted column id: $reorderFlexId, is new target: $isNewDragTarget');
     if (isNewDragTarget) {
       /// Remove the phantom in the previous column.
       _removePhantom(phantomRecord!.toColumnId);
@@ -196,8 +172,7 @@ class BoardPhantomController extends OverlapReorderFlexDragTargetDelegate
   }
 
   @override
-  void updateDragTargetData(
-      String reorderFlexId, FlexDragTargetData dragTargetData, int index) {
+  void updateDragTargetData(String reorderFlexId, FlexDragTargetData dragTargetData, int index) {
     phantomRecord?.updateInsertedIndex(index);
 
     assert(phantomRecord != null);
@@ -228,34 +203,29 @@ class PhantomRecord {
     if (fromColumnIndex == index) {
       return;
     }
-    Log.info(
-        '[$PhantomRecord] Update Column$fromColumnId remove position to $index');
+    Log.debug('[$PhantomRecord] Update Column$fromColumnId remove position to $index');
     fromColumnIndex = index;
   }
 
   void updateInsertedIndex(int index) {
     if (toColumnIndex == index) {
-      Log.info(
-          '[$PhantomRecord] Column$toColumnId toColumnIndex: $toColumnIndex, index: $index');
       return;
     }
 
-    Log.info(
-        '[$PhantomRecord] Update Column$toColumnId phantom position to $index');
+    Log.debug('[$PhantomRecord] Column$toColumnId update position $toColumnIndex -> $index');
     toColumnIndex = index;
   }
 
   @override
   String toString() {
-    return '$fromColumnId:$fromColumnIndex to $toColumnId:$toColumnIndex';
+    return 'Column$fromColumnId:$fromColumnIndex to Column$toColumnId:$toColumnIndex';
   }
 }
 
 class PhantomColumnItem extends ColumnItem {
   final PassthroughPhantomContext phantomContext;
 
-  PhantomColumnItem(PassthroughPhantomContext insertedPhantom)
-      : phantomContext = insertedPhantom;
+  PhantomColumnItem(PassthroughPhantomContext insertedPhantom) : phantomContext = insertedPhantom;
 
   @override
   bool get isPhantom => true;
@@ -265,9 +235,8 @@ 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