diff --git a/frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/drag_state.dart b/frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/drag_state.dart index a5496bc9d8..9a5725b6a4 100644 --- a/frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/drag_state.dart +++ b/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); diff --git a/frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/drag_target_inteceptor.dart b/frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/drag_target_inteceptor.dart index 0495eeae14..19c0c0f05d 100644 --- a/frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/drag_target_inteceptor.dart +++ b/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 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 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, ); } diff --git a/frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/reorder_flex.dart b/frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/reorder_flex.dart index a7c4940f6d..b451aaf0e6 100644 --- a/frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/reorder_flex.dart +++ b/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 children; @@ -68,16 +69,11 @@ class ReorderFlex extends StatefulWidget with DraggingReorderFlex { @override State createState() => ReorderFlexState(); - @override String get reorderFlexId => dataSource.identifier; - - @override - ReoderFlexItem itemAtIndex(int index) { - return dataSource.items[index]; - } } -class ReorderFlexState extends State with ReorderFlexMinxi, TickerProviderStateMixin { +class ReorderFlexState extends State + with ReorderFlexMinxi, TickerProviderStateMixin { /// Controls scrolls and measures scroll progress. late ScrollController _scrollController; ScrollPosition? _attachedScrollPosition; @@ -113,7 +109,9 @@ class ReorderFlexState extends State 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 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 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 with ReorderFlexMinxi, TickerP Widget child, int dragTargetIndex, ) { - final ReoderFlexItem reorderFlexItem = widget.dataSource.items[dragTargetIndex]; + final ReoderFlexItem reorderFlexItem = + widget.dataSource.items[dragTargetIndex]; return ReorderDragTarget( 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 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 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 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 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 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) { diff --git a/frontend/app_flowy/packages/flowy_board/lib/src/widgets/phantom/phantom_controller.dart b/frontend/app_flowy/packages/flowy_board/lib/src/widgets/phantom/phantom_controller.dart index 6e2a5195f3..a7be370c71 100644 --- a/frontend/app_flowy/packages/flowy_board/lib/src/widgets/phantom/phantom_controller.dart +++ b/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