瀏覽代碼

chore: update board layout, support footer and header

appflowy 2 年之前
父節點
當前提交
dbc5de2968

+ 14 - 1
frontend/app_flowy/packages/flowy_board/example/lib/multi_board_list_example.dart

@@ -46,9 +46,22 @@ class _MultiBoardListExampleState extends State<MultiBoardListExample> {
     return Board(
       dataController: boardData,
       background: Container(color: Colors.red),
-      builder: (context, item) {
+      footBuilder: (context, columnData) {
+        return Container(
+          color: Colors.purple,
+          height: 30,
+        );
+      },
+      headerBuilder: (context, columnData) {
+        return Container(
+          color: Colors.yellow,
+          height: 30,
+        );
+      },
+      cardBuilder: (context, item) {
         return _RowWidget(item: item as TextItem, key: ObjectKey(item));
       },
+      columnConstraints: const BoxConstraints.tightFor(width: 240),
     );
   }
 }

+ 1 - 1
frontend/app_flowy/packages/flowy_board/example/lib/single_board_list_example.dart

@@ -28,7 +28,7 @@ class _SingleBoardListExampleState extends State<SingleBoardListExample> {
   Widget build(BuildContext context) {
     return Board(
       dataController: boardData,
-      builder: (context, item) {
+      cardBuilder: (context, item) {
         return _RowWidget(item: item as TextItem, key: ObjectKey(item));
       },
     );

+ 1 - 2
frontend/app_flowy/packages/flowy_board/lib/src/rendering/board_overlay.dart

@@ -13,8 +13,7 @@ class BoardOverlayEntry {
   /// Whether this entry occludes the entire overlay.
   ///
   /// If an entry claims to be opaque, then, for efficiency, the overlay will
-  /// skip building entries below that entry unless they have [maintainState]
-  /// set.
+  /// skip building entries below that entry.
   bool get opaque => _opaque;
   bool _opaque;
 

+ 28 - 31
frontend/app_flowy/packages/flowy_board/lib/src/widgets/board.dart

@@ -20,25 +20,37 @@ class Board extends StatelessWidget {
   /// Defaults to 0.0.
   final double runSpacing;
 
+  ///
   final Widget? background;
 
-  final BoardColumnItemWidgetBuilder builder;
+  ///
+  final BoardColumnCardBuilder cardBuilder;
+
+  ///
+  final BoardColumnHeaderBuilder? headerBuilder;
+
+  ///
+  final BoardColumnFooterBuilder? footBuilder;
 
   ///
   final BoardDataController dataController;
 
+  final BoxConstraints columnConstraints;
+
   ///
-  final BoardPhantomController passthroughPhantomContorller;
+  final BoardPhantomController phantomController;
 
   Board({
     required this.dataController,
-    required this.builder,
+    required this.cardBuilder,
     this.spacing = 10.0,
     this.runSpacing = 0.0,
     this.background,
+    this.footBuilder,
+    this.headerBuilder,
+    this.columnConstraints = const BoxConstraints(maxWidth: 200),
     Key? key,
-  })  : passthroughPhantomContorller =
-            BoardPhantomController(delegate: dataController),
+  })  : phantomController = BoardPhantomController(delegate: dataController),
         super(key: key);
 
   @override
@@ -51,41 +63,25 @@ class Board extends StatelessWidget {
           List<String> acceptColumns =
               dataController.columnControllers.keys.toList();
 
-          dataController.columnControllers.forEach((columnId, dataController) {
-            Widget child =
-                buildBoardColumn(columnId, acceptColumns, dataController);
-            if (children.isEmpty) {
-              // children.add(SizedBox(width: spacing));
-            }
-            // if (background != null) {
-            //   child = Stack(children: [
-            //     background!,
-            //     child,
-            //   ]);
-            // }
-            // children.add(Expanded(key: ValueKey(columnId), child: child));
+          dataController.columnControllers.forEach((columnId, controller) {
+            Widget child = _buildColumn(columnId, acceptColumns, controller);
             children.add(child);
-            // children.add(SizedBox(width: spacing));
           });
 
           return BoardColumnContainer(
             onReorder: (fromIndex, toIndex) {},
             boardDataController: dataController,
+            background: background,
+            spacing: spacing,
             children: children,
           );
-
-          // return Row(
-          //   crossAxisAlignment: CrossAxisAlignment.start,
-          //   mainAxisAlignment: MainAxisAlignment.spaceEvenly,
-          //   children: children,
-          // );
         },
       ),
     );
   }
 
   ///
-  Widget buildBoardColumn(
+  Widget _buildColumn(
     String columnId,
     List<String> acceptColumns,
     BoardColumnDataController dataController,
@@ -95,18 +91,19 @@ class Board extends StatelessWidget {
       value: dataController,
       child: Consumer<BoardColumnDataController>(
         builder: (context, value, child) {
-          return SizedBox(
-            width: 200,
+          return ConstrainedBox(
+            constraints: columnConstraints,
             child: BoardColumnWidget(
-              header: Container(color: Colors.yellow, height: 30),
-              builder: builder,
+              headerBuilder: headerBuilder,
+              footBuilder: footBuilder,
+              cardBuilder: cardBuilder,
               acceptColumns: acceptColumns,
               dataController: dataController,
               scrollController: ScrollController(),
               onReorder: (_, int fromIndex, int toIndex) {
                 dataController.move(fromIndex, toIndex);
               },
-              phantomController: passthroughPhantomContorller,
+              phantomController: phantomController,
             ),
           );
         },

+ 83 - 63
frontend/app_flowy/packages/flowy_board/lib/src/widgets/board_column/board_column.dart

@@ -4,34 +4,33 @@ import '../../rendering/board_overlay.dart';
 import '../../utils/log.dart';
 import '../phantom/phantom_controller.dart';
 import '../flex/reorder_flex.dart';
-import '../flex/drag_state.dart';
-import '../flex/reorder_flex_ext.dart';
+import '../flex/drag_target_inteceptor.dart';
 import 'data_controller.dart';
 
-typedef OnDragStarted = void Function(int index);
-typedef OnDragEnded = void Function(String listId);
-typedef OnReorder = void Function(String listId, int fromIndex, int toIndex);
-typedef OnDeleted = void Function(String listId, int deletedIndex);
-typedef OnInserted = void Function(String listId, int insertedIndex);
-typedef OnPassedInPhantom = void Function(
-  String listId,
-  FlexDragTargetData dragTargetData,
-  int phantomIndex,
-);
-
-typedef BoardColumnItemWidgetBuilder = Widget Function(
+typedef OnColumnDragStarted = void Function(int index);
+typedef OnColumnDragEnded = void Function(String listId);
+typedef OnColumnReorder = void Function(
+    String listId, int fromIndex, int toIndex);
+typedef OnColumnDeleted = void Function(String listId, int deletedIndex);
+typedef OnColumnInserted = void Function(String listId, int insertedIndex);
+
+typedef BoardColumnCardBuilder = Widget Function(
     BuildContext context, ColumnItem item);
 
+typedef BoardColumnHeaderBuilder = Widget Function(
+    BuildContext context, BoardColumnData columnData);
+
+typedef BoardColumnFooterBuilder = Widget Function(
+    BuildContext context, BoardColumnData columnData);
+
 class BoardColumnWidget extends StatefulWidget {
-  final Widget? header;
-  final Widget? footer;
   final BoardColumnDataController dataController;
   final ScrollController? scrollController;
   final ReorderFlexConfig config;
 
-  final OnDragStarted? onDragStarted;
-  final OnReorder onReorder;
-  final OnDragEnded? onDragEnded;
+  final OnColumnDragStarted? onDragStarted;
+  final OnColumnReorder onReorder;
+  final OnColumnDragEnded? onDragEnded;
 
   final BoardPhantomController phantomController;
 
@@ -39,18 +38,25 @@ class BoardColumnWidget extends StatefulWidget {
 
   final List<String> acceptColumns;
 
-  final BoardColumnItemWidgetBuilder builder;
+  final BoardColumnCardBuilder cardBuilder;
+
+  final BoardColumnHeaderBuilder? headerBuilder;
+
+  final BoardColumnFooterBuilder? footBuilder;
+
+  final double? spacing;
 
   const BoardColumnWidget({
     Key? key,
-    this.header,
-    this.footer,
-    required this.builder,
+    this.headerBuilder,
+    this.footBuilder,
+    required this.cardBuilder,
     required this.onReorder,
     required this.dataController,
     required this.phantomController,
     required this.acceptColumns,
     this.config = const ReorderFlexConfig(),
+    this.spacing,
     this.onDragStarted,
     this.scrollController,
     this.onDragEnded,
@@ -69,45 +75,59 @@ class _BoardColumnWidgetState extends State<BoardColumnWidget> {
   @override
   void initState() {
     _overlayEntry = BoardOverlayEntry(
-        builder: (BuildContext context) {
-          final children = widget.dataController.items
-              .map((item) => _buildWidget(context, item))
-              .toList();
-
-          final dragTargetExtension = ReorderFlextDragTargetExtension(
-            reorderFlexId: widget.columnId,
-            delegate: widget.phantomController,
-            acceptReorderFlexIds: widget.acceptColumns,
-            draggableTargetBuilder: PhantomReorderDraggableBuilder(),
-          );
-
-          return ReorderFlex(
-            key: widget.key,
-            header: widget.header,
-            footer: widget.footer,
-            scrollController: widget.scrollController,
-            config: widget.config,
-            onDragStarted: (index) {
-              widget.phantomController.columnStartDragging(widget.columnId);
-              widget.onDragStarted?.call(index);
-            },
-            onReorder: ((fromIndex, toIndex) {
-              if (widget.phantomController.isFromColumn(widget.columnId)) {
-                widget.onReorder(widget.columnId, fromIndex, toIndex);
-                widget.phantomController.transformIndex(fromIndex, toIndex);
-              }
-            }),
-            onDragEnded: () {
-              widget.phantomController.columnEndDragging(widget.columnId);
-              widget.onDragEnded?.call(widget.columnId);
-              _printItems(widget.dataController);
-            },
-            dataSource: widget.dataController,
-            dragTargetExtension: dragTargetExtension,
-            children: children,
-          );
-        },
-        opaque: false);
+      builder: (BuildContext context) {
+        final children = widget.dataController.items
+            .map((item) => _buildWidget(context, item))
+            .toList();
+
+        final header = widget.headerBuilder
+            ?.call(context, widget.dataController.columnData);
+
+        final footer =
+            widget.footBuilder?.call(context, widget.dataController.columnData);
+
+        final interceptor = CrossReorderFlexDragTargetInterceptor(
+          reorderFlexId: widget.columnId,
+          delegate: widget.phantomController,
+          acceptReorderFlexIds: widget.acceptColumns,
+          draggableTargetBuilder: PhantomDraggableBuilder(),
+        );
+
+        final reorderFlex = ReorderFlex(
+          key: widget.key,
+          scrollController: widget.scrollController,
+          config: widget.config,
+          onDragStarted: (index) {
+            widget.phantomController.columnStartDragging(widget.columnId);
+            widget.onDragStarted?.call(index);
+          },
+          onReorder: ((fromIndex, toIndex) {
+            if (widget.phantomController.isFromColumn(widget.columnId)) {
+              widget.onReorder(widget.columnId, fromIndex, toIndex);
+              widget.phantomController.transformIndex(fromIndex, toIndex);
+            }
+          }),
+          onDragEnded: () {
+            widget.phantomController.columnEndDragging(widget.columnId);
+            widget.onDragEnded?.call(widget.columnId);
+            _printItems(widget.dataController);
+          },
+          dataSource: widget.dataController,
+          interceptor: interceptor,
+          spacing: widget.spacing,
+          children: children,
+        );
+
+        return Column(
+          children: [
+            if (header != null) header,
+            Expanded(child: reorderFlex),
+            if (footer != null) footer,
+          ],
+        );
+      },
+      opaque: false,
+    );
     super.initState();
   }
 
@@ -127,7 +147,7 @@ class _BoardColumnWidgetState extends State<BoardColumnWidget> {
         passthroughPhantomContext: item.phantomContext,
       );
     } else {
-      return widget.builder(context, item);
+      return widget.cardBuilder(context, item);
     }
   }
 }

+ 15 - 18
frontend/app_flowy/packages/flowy_board/lib/src/widgets/column_container.dart

@@ -1,12 +1,10 @@
 import 'package:flutter/material.dart';
 
+import '../../flowy_board.dart';
 import '../rendering/board_overlay.dart';
 import 'flex/reorder_flex.dart';
-import 'board.dart';
 
 class BoardColumnContainer extends StatefulWidget {
-  final Widget? header;
-  final Widget? footer;
   final ScrollController? scrollController;
   final OnDragStarted? onDragStarted;
   final OnReorder onReorder;
@@ -15,6 +13,7 @@ class BoardColumnContainer extends StatefulWidget {
   final List<Widget> children;
   final EdgeInsets? padding;
   final Widget? background;
+  final double spacing;
   final ReorderFlexConfig config;
 
   const BoardColumnContainer({
@@ -23,11 +22,10 @@ class BoardColumnContainer extends StatefulWidget {
     required this.children,
     this.onDragStarted,
     this.onDragEnded,
-    this.header,
-    this.footer,
     this.scrollController,
     this.padding,
     this.background,
+    this.spacing = 0.0,
     this.config = const ReorderFlexConfig(),
     Key? key,
   }) : super(key: key);
@@ -47,8 +45,6 @@ class _BoardColumnContainerState extends State<BoardColumnContainer> {
         builder: (BuildContext context) {
           Widget reorderFlex = ReorderFlex(
             key: widget.key,
-            header: widget.header,
-            footer: widget.footer,
             scrollController: widget.scrollController,
             config: widget.config,
             onDragStarted: (index) {},
@@ -56,6 +52,7 @@ class _BoardColumnContainerState extends State<BoardColumnContainer> {
             onDragEnded: () {},
             dataSource: widget.boardDataController,
             direction: Axis.horizontal,
+            spacing: widget.spacing,
             children: widget.children,
           );
 
@@ -65,17 +62,7 @@ class _BoardColumnContainerState extends State<BoardColumnContainer> {
               child: reorderFlex,
             );
           }
-
-          return Expanded(
-              child: Stack(
-            alignment: AlignmentDirectional.center,
-            children: [
-              Container(
-                color: Colors.red,
-              ),
-              reorderFlex
-            ],
-          ));
+          return _wrapStack(reorderFlex);
         },
         opaque: false);
     super.initState();
@@ -88,4 +75,14 @@ class _BoardColumnContainerState extends State<BoardColumnContainer> {
       initialEntries: [_overlayEntry],
     );
   }
+
+  Widget _wrapStack(Widget child) {
+    return Stack(
+      alignment: AlignmentDirectional.topStart,
+      children: [
+        if (widget.background != null) widget.background!,
+        child,
+      ],
+    );
+  }
 }

+ 4 - 3
frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/drag_target.dart

@@ -4,7 +4,7 @@ abstract class DragTargetData {
   int get draggingIndex;
 }
 
-abstract class ReorderDraggableTargetBuilder {
+abstract class ReorderFlexDraggableTargetBuilder {
   Widget? build<T extends DragTargetData>(
       BuildContext context,
       Widget child,
@@ -51,7 +51,7 @@ class ReorderDragTarget<T extends DragTargetData> extends StatefulWidget {
   /// the target.
   final void Function(T dragTargetData)? onLeave;
 
-  final ReorderDraggableTargetBuilder? draggableTargetBuilder;
+  final ReorderFlexDraggableTargetBuilder? draggableTargetBuilder;
 
   ReorderDragTarget({
     Key? key,
@@ -158,9 +158,10 @@ class _ReorderDragTargetState<T extends DragTargetData>
       transform: Matrix4.rotationZ(0),
       alignment: FractionalOffset.topLeft,
       child: Material(
-        elevation: 3.0,
+        elevation: 6.0,
         color: Colors.transparent,
         borderRadius: BorderRadius.zero,
+        clipBehavior: Clip.hardEdge,
         child: ConstrainedBox(constraints: constraints, child: child),
       ),
     );

+ 114 - 0
frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/drag_target_inteceptor.dart

@@ -0,0 +1,114 @@
+import 'package:flutter/material.dart';
+
+import '../../utils/log.dart';
+import 'drag_state.dart';
+import 'drag_target.dart';
+import 'reorder_flex.dart';
+
+abstract class ReorderFlexDragTargetInterceptor {
+  bool canHandler(FlexDragTargetData dragTargetData);
+
+  bool onWillAccept(
+    BuildContext context,
+    ReorderFlexState reorderFlexState,
+    FlexDragTargetData dragTargetData,
+    int itemIndex,
+  );
+
+  void onAccept(FlexDragTargetData dragTargetData);
+
+  void onLeave(FlexDragTargetData dragTargetData);
+
+  ReorderFlexDraggableTargetBuilder? get draggableTargetBuilder;
+}
+
+abstract class CrossReorderFlexDragTargetDelegate {
+  bool acceptNewDragTargetData(
+    String columnId,
+    FlexDragTargetData dragTargetData,
+    int index,
+  );
+  void updateDragTargetData(
+    String columnId,
+    FlexDragTargetData dragTargetData,
+    int index,
+  );
+}
+
+class CrossReorderFlexDragTargetInterceptor
+    extends ReorderFlexDragTargetInterceptor {
+  final String reorderFlexId;
+  final List<String> acceptReorderFlexIds;
+  final CrossReorderFlexDragTargetDelegate delegate;
+  @override
+  final ReorderFlexDraggableTargetBuilder? draggableTargetBuilder;
+
+  CrossReorderFlexDragTargetInterceptor({
+    required this.reorderFlexId,
+    required this.delegate,
+    required this.acceptReorderFlexIds,
+    this.draggableTargetBuilder,
+  });
+
+  @override
+  bool canHandler(FlexDragTargetData dragTargetData) {
+    if (acceptReorderFlexIds.isEmpty) {
+      return true;
+    }
+
+    if (acceptReorderFlexIds.contains(dragTargetData.reorderFlexId)) {
+      /// If the columnId equal to the dragTargetData's columnId,
+      /// it means the dragTarget is dragging on the top of its own list.
+      /// Otherwise, it means the dargTarget was moved to another list.
+      return reorderFlexId != dragTargetData.reorderFlexId;
+    } else {
+      return false;
+    }
+  }
+
+  @override
+  bool onWillAccept(
+    BuildContext context,
+    ReorderFlexState reorderFlexState,
+    FlexDragTargetData dragTargetData,
+    int itemIndex,
+  ) {
+    final isNewDragTarget = delegate.acceptNewDragTargetData(
+      reorderFlexId,
+      dragTargetData,
+      itemIndex,
+    );
+
+    if (isNewDragTarget == false) {
+      delegate.updateDragTargetData(
+        reorderFlexId,
+        dragTargetData,
+        itemIndex,
+      );
+
+      reorderFlexState.onWillAccept(
+        context,
+        dragTargetData.draggingIndex,
+        itemIndex,
+      );
+    } else {
+      Log.debug(
+          '[$CrossReorderFlexDragTargetInterceptor] move Column${dragTargetData.reorderFlexId}:${dragTargetData.draggingIndex} '
+          'to Column$reorderFlexId:$itemIndex');
+    }
+
+    return true;
+  }
+
+  @override
+  void onAccept(FlexDragTargetData dragTargetData) {
+    Log.trace(
+        '[$CrossReorderFlexDragTargetInterceptor] Column$reorderFlexId on onAccept');
+  }
+
+  @override
+  void onLeave(FlexDragTargetData dragTargetData) {
+    Log.trace(
+        '[$CrossReorderFlexDragTargetInterceptor] Column$reorderFlexId on leave');
+  }
+}

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

@@ -2,12 +2,11 @@ import 'dart:math';
 
 import 'package:flutter/material.dart';
 import 'package:flutter/rendering.dart';
-
 import '../../utils/log.dart';
 import 'reorder_mixin.dart';
 import 'drag_target.dart';
 import 'drag_state.dart';
-import 'reorder_flex_ext.dart';
+import 'drag_target_inteceptor.dart';
 
 typedef OnDragStarted = void Function(int index);
 typedef OnDragEnded = void Function();
@@ -33,14 +32,13 @@ class ReorderFlexConfig {
 }
 
 class ReorderFlex extends StatefulWidget with DraggingReorderFlex {
-  final Widget? header;
-  final Widget? footer;
   final ReorderFlexConfig config;
 
   final List<Widget> children;
   final EdgeInsets? padding;
+  final double? spacing;
   final Axis direction;
-  final MainAxisAlignment mainAxisAlignment = MainAxisAlignment.spaceEvenly;
+  final MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start;
   final ScrollController? scrollController;
 
   final OnDragStarted? onDragStarted;
@@ -49,12 +47,10 @@ class ReorderFlex extends StatefulWidget with DraggingReorderFlex {
 
   final ReoderFlextDataSource dataSource;
 
-  final ReorderFlextDragTargetExtension? dragTargetExtension;
+  final ReorderFlexDragTargetInterceptor? interceptor;
 
   const ReorderFlex({
     Key? key,
-    this.header,
-    this.footer,
     this.scrollController,
     required this.dataSource,
     required this.children,
@@ -62,9 +58,9 @@ class ReorderFlex extends StatefulWidget with DraggingReorderFlex {
     required this.onReorder,
     this.onDragStarted,
     this.onDragEnded,
-    this.dragTargetExtension,
-    // ignore: unused_element
+    this.interceptor,
     this.padding,
+    this.spacing,
     this.direction = Axis.vertical,
   }) : super(key: key);
 
@@ -136,23 +132,19 @@ class ReorderFlexState extends State<ReorderFlex>
   @override
   Widget build(BuildContext context) {
     final List<Widget> children = [];
-    if (widget.header != null) {
-      children.add(widget.header!);
-    }
 
     for (int i = 0; i < widget.children.length; i += 1) {
       Widget child = widget.children[i];
+      if (widget.spacing != null) {
+        children.add(SizedBox(width: widget.spacing!));
+      }
+
       final wrapChild = _wrap(child, i);
       children.add(wrapChild);
     }
 
-    if (widget.footer != null) {
-      children.add(widget.footer!);
-    }
-
-    return _wrapScrollView(
-      child: _wrapContainer(children),
-    );
+    final child = _wrapContainer(children);
+    return _wrapScrollView(child: child);
   }
 
   @override
@@ -316,54 +308,49 @@ class ReorderFlexState extends State<ReorderFlex>
         });
       },
       onWillAccept: (FlexDragTargetData dragTargetData) {
-        Log.debug(
-            '[$ReorderDragTarget] ${widget.dataSource.identifier} on will accept, count: ${widget.dataSource.items.length}');
         assert(widget.dataSource.items.length > childIndex);
 
-        if (_requestDragExtensionToHanlder(
+        if (_interceptDragTarget(
           dragTargetData,
-          (extension) {
-            extension.onWillAccept(
-              this,
-              builderContext,
-              dragTargetData,
-              dragState.isDragging(),
-              dragTargetData.draggingIndex,
-              childIndex,
-            );
-          },
+          (interceptor) => interceptor.onWillAccept(
+            builderContext,
+            this,
+            dragTargetData,
+            childIndex,
+          ),
         )) {
           return true;
         } else {
+          Log.debug(
+              '[$ReorderDragTarget] ${widget.dataSource.identifier} on will accept, count: ${widget.dataSource.items.length}');
           final dragIndex = dragTargetData.draggingIndex;
           return onWillAccept(builderContext, dragIndex, childIndex);
         }
       },
       onAccept: (dragTargetData) {
-        _requestDragExtensionToHanlder(
+        _interceptDragTarget(
           dragTargetData,
-          (extension) => extension.onAccept(dragTargetData),
+          (interceptor) => interceptor.onAccept(dragTargetData),
         );
       },
       onLeave: (dragTargetData) {
-        _requestDragExtensionToHanlder(
+        _interceptDragTarget(
           dragTargetData,
-          (extension) => extension.onLeave(dragTargetData),
+          (interceptor) => interceptor.onLeave(dragTargetData),
         );
       },
-      draggableTargetBuilder:
-          widget.dragTargetExtension?.draggableTargetBuilder,
+      draggableTargetBuilder: widget.interceptor?.draggableTargetBuilder,
       child: child,
     );
   }
 
-  bool _requestDragExtensionToHanlder(
+  bool _interceptDragTarget(
     FlexDragTargetData dragTargetData,
-    void Function(ReorderFlextDragTargetExtension) callback,
+    void Function(ReorderFlexDragTargetInterceptor) callback,
   ) {
-    final extension = widget.dragTargetExtension;
-    if (extension != null && extension.canHandler(dragTargetData)) {
-      callback(extension);
+    final interceptor = widget.interceptor;
+    if (interceptor != null && interceptor.canHandler(dragTargetData)) {
+      callback(interceptor);
       return true;
     } else {
       return false;
@@ -466,14 +453,16 @@ class ReorderFlexState extends State<ReorderFlex>
       case Axis.horizontal:
         return Row(
           mainAxisSize: MainAxisSize.min,
-          mainAxisAlignment: MainAxisAlignment.start,
+          crossAxisAlignment: CrossAxisAlignment.start,
+          mainAxisAlignment: widget.mainAxisAlignment,
           children: children,
         );
       case Axis.vertical:
       default:
         return Column(
           mainAxisSize: MainAxisSize.min,
-          mainAxisAlignment: MainAxisAlignment.start,
+          crossAxisAlignment: CrossAxisAlignment.start,
+          mainAxisAlignment: widget.mainAxisAlignment,
           children: children,
         );
     }
@@ -514,9 +503,7 @@ class ReorderFlexState extends State<ReorderFlex>
           curve: Curves.easeInOut,
         )
             .then((void value) {
-          setState(() {
-            _scrolling = false;
-          });
+          setState(() => _scrolling = false);
         });
       }
     }

+ 0 - 78
frontend/app_flowy/packages/flowy_board/lib/src/widgets/flex/reorder_flex_ext.dart

@@ -1,78 +0,0 @@
-import 'package:flutter/material.dart';
-
-import '../../utils/log.dart';
-import 'drag_state.dart';
-import 'drag_target.dart';
-import 'reorder_flex.dart';
-
-abstract class DragTargetExtensionDelegate {
-  bool acceptNewDragTargetData(
-    String columnId,
-    FlexDragTargetData dragTargetData,
-    int index,
-  );
-  void updateDragTargetData(
-    String columnId,
-    FlexDragTargetData dragTargetData,
-    int index,
-  );
-}
-
-class ReorderFlextDragTargetExtension {
-  final String reorderFlexId;
-  final List<String> acceptReorderFlexIds;
-  final DragTargetExtensionDelegate delegate;
-  final ReorderDraggableTargetBuilder? draggableTargetBuilder;
-
-  ReorderFlextDragTargetExtension({
-    required this.reorderFlexId,
-    required this.delegate,
-    required this.acceptReorderFlexIds,
-    this.draggableTargetBuilder,
-  });
-
-  bool canHandler(FlexDragTargetData dragTargetData) {
-    /// If the columnId equal to the dragTargetData's columnId,
-    /// it means the dragTarget is dragging on the top of its own list.
-    /// Otherwise, it means the dargTarget was moved to another list.
-    ///
-    if (!acceptReorderFlexIds.contains(dragTargetData.reorderFlexId)) {
-      return false;
-    }
-
-    return reorderFlexId != dragTargetData.reorderFlexId;
-  }
-
-  bool onWillAccept(
-    ReorderFlexState reorderFlexState,
-    BuildContext context,
-    FlexDragTargetData dragTargetData,
-    bool isDragging,
-    int dragIndex,
-    int itemIndex,
-  ) {
-    final isNewDragTarget = delegate.acceptNewDragTargetData(
-        reorderFlexId, dragTargetData, itemIndex);
-
-    if (isNewDragTarget == false) {
-      delegate.updateDragTargetData(reorderFlexId, dragTargetData, itemIndex);
-      reorderFlexState.onWillAccept(context, dragIndex, itemIndex);
-    } else {
-      Log.debug(
-          '[$ReorderFlextDragTargetExtension] move Column${dragTargetData.reorderFlexId}:${dragTargetData.draggingIndex} '
-          'to Column$reorderFlexId:$itemIndex');
-    }
-
-    return true;
-  }
-
-  void onAccept(FlexDragTargetData dragTargetData) {
-    Log.trace(
-        '[$ReorderFlextDragTargetExtension] Column$reorderFlexId on onAccept');
-  }
-
-  void onLeave(FlexDragTargetData dragTargetData) {
-    Log.trace(
-        '[$ReorderFlextDragTargetExtension] Column$reorderFlexId on leave');
-  }
-}

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

@@ -3,7 +3,7 @@ import '../../../flowy_board.dart';
 import '../../utils/log.dart';
 import '../flex/drag_state.dart';
 import '../flex/drag_target.dart';
-import '../flex/reorder_flex_ext.dart';
+import '../flex/drag_target_inteceptor.dart';
 import 'phantom_state.dart';
 
 abstract class BoardPhantomControllerDelegate {
@@ -14,7 +14,7 @@ mixin ColumnDataPhantomMixim {
   BoardColumnDataController? get;
 }
 
-class BoardPhantomController extends DragTargetExtensionDelegate {
+class BoardPhantomController extends CrossReorderFlexDragTargetDelegate {
   final BoardPhantomControllerDelegate delegate;
 
   PhantomRecord? phantomRecord;
@@ -313,7 +313,7 @@ class PassthroughPhantomWidget extends PhantomWidget {
         );
 }
 
-class PhantomReorderDraggableBuilder extends ReorderDraggableTargetBuilder {
+class PhantomDraggableBuilder extends ReorderFlexDraggableTargetBuilder {
   @override
   Widget? build<T extends DragTargetData>(
     BuildContext context,