mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: scroll to bottom after post frame
This commit is contained in:
@ -72,16 +72,19 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
createRow: (groupId) async {
|
createRow: (groupId) async {
|
||||||
final result = await _gridDataController.createBoardCard(groupId);
|
final result = await _gridDataController.createBoardCard(groupId);
|
||||||
result.fold(
|
result.fold(
|
||||||
(rowPB) {
|
(_) {},
|
||||||
emit(state.copyWith(editingRow: some(rowPB)));
|
|
||||||
},
|
|
||||||
(err) => Log.error(err),
|
(err) => Log.error(err),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
didCreateRow: (String groupId, RowPB row) {
|
||||||
|
emit(state.copyWith(
|
||||||
|
editingRow: Some(BoardEditingRow(columnId: groupId, row: row)),
|
||||||
|
));
|
||||||
|
},
|
||||||
endEditRow: (rowId) {
|
endEditRow: (rowId) {
|
||||||
assert(state.editingRow.isSome());
|
assert(state.editingRow.isSome());
|
||||||
state.editingRow.fold(() => null, (row) {
|
state.editingRow.fold(() => null, (editingRow) {
|
||||||
assert(row.id == rowId);
|
assert(editingRow.row.id == rowId);
|
||||||
emit(state.copyWith(editingRow: none()));
|
emit(state.copyWith(editingRow: none()));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -137,7 +140,12 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
|
|
||||||
void initializeGroups(List<GroupPB> groups) {
|
void initializeGroups(List<GroupPB> groups) {
|
||||||
for (final group in groups) {
|
for (final group in groups) {
|
||||||
final delegate = GroupControllerDelegateImpl(boardController);
|
final delegate = GroupControllerDelegateImpl(
|
||||||
|
controller: boardController,
|
||||||
|
didAddColumnItem: (groupId, row) {
|
||||||
|
add(BoardEvent.didCreateRow(groupId, row));
|
||||||
|
},
|
||||||
|
);
|
||||||
final controller = GroupController(
|
final controller = GroupController(
|
||||||
gridId: state.gridId,
|
gridId: state.gridId,
|
||||||
group: group,
|
group: group,
|
||||||
@ -222,8 +230,10 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class BoardEvent with _$BoardEvent {
|
class BoardEvent with _$BoardEvent {
|
||||||
const factory BoardEvent.initial() = InitialGrid;
|
const factory BoardEvent.initial() = InitialBrid;
|
||||||
const factory BoardEvent.createRow(String groupId) = _CreateRow;
|
const factory BoardEvent.createRow(String groupId) = _CreateRow;
|
||||||
|
const factory BoardEvent.didCreateRow(String groupId, RowPB row) =
|
||||||
|
_DidCreateRow;
|
||||||
const factory BoardEvent.endEditRow(String rowId) = _EndEditRow;
|
const factory BoardEvent.endEditRow(String rowId) = _EndEditRow;
|
||||||
const factory BoardEvent.didReceiveError(FlowyError error) = _DidReceiveError;
|
const factory BoardEvent.didReceiveError(FlowyError error) = _DidReceiveError;
|
||||||
const factory BoardEvent.didReceiveGridUpdate(
|
const factory BoardEvent.didReceiveGridUpdate(
|
||||||
@ -239,7 +249,7 @@ class BoardState with _$BoardState {
|
|||||||
required String gridId,
|
required String gridId,
|
||||||
required Option<GridPB> grid,
|
required Option<GridPB> grid,
|
||||||
required List<String> groupIds,
|
required List<String> groupIds,
|
||||||
required Option<RowPB> editingRow,
|
required Option<BoardEditingRow> editingRow,
|
||||||
required GridLoadingState loadingState,
|
required GridLoadingState loadingState,
|
||||||
required Option<FlowyError> noneOrError,
|
required Option<FlowyError> noneOrError,
|
||||||
}) = _BoardState;
|
}) = _BoardState;
|
||||||
@ -303,16 +313,17 @@ class BoardColumnItem extends AFColumnItem {
|
|||||||
|
|
||||||
class GroupControllerDelegateImpl extends GroupControllerDelegate {
|
class GroupControllerDelegateImpl extends GroupControllerDelegate {
|
||||||
final AFBoardDataController controller;
|
final AFBoardDataController controller;
|
||||||
|
final void Function(String, RowPB) didAddColumnItem;
|
||||||
|
|
||||||
GroupControllerDelegateImpl(this.controller);
|
GroupControllerDelegateImpl({
|
||||||
|
required this.controller,
|
||||||
|
required this.didAddColumnItem,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void insertRow(GroupPB group, RowPB row, int? index) {
|
void insertRow(GroupPB group, RowPB row, int? index) {
|
||||||
if (index != null) {
|
if (index != null) {
|
||||||
final item = BoardColumnItem(
|
final item = BoardColumnItem(row: row, fieldId: group.fieldId);
|
||||||
row: row,
|
|
||||||
fieldId: group.fieldId,
|
|
||||||
);
|
|
||||||
controller.insertColumnItem(group.groupId, index, item);
|
controller.insertColumnItem(group.groupId, index, item);
|
||||||
} else {
|
} else {
|
||||||
final item = BoardColumnItem(
|
final item = BoardColumnItem(
|
||||||
@ -321,6 +332,7 @@ class GroupControllerDelegateImpl extends GroupControllerDelegate {
|
|||||||
requestFocus: true,
|
requestFocus: true,
|
||||||
);
|
);
|
||||||
controller.addColumnItem(group.groupId, item);
|
controller.addColumnItem(group.groupId, item);
|
||||||
|
didAddColumnItem(group.groupId, row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,10 +344,21 @@ class GroupControllerDelegateImpl extends GroupControllerDelegate {
|
|||||||
@override
|
@override
|
||||||
void updateRow(GroupPB group, RowPB row) {
|
void updateRow(GroupPB group, RowPB row) {
|
||||||
controller.updateColumnItem(
|
controller.updateColumnItem(
|
||||||
group.groupId,
|
group.groupId,
|
||||||
BoardColumnItem(
|
BoardColumnItem(
|
||||||
row: row,
|
row: row,
|
||||||
fieldId: group.fieldId,
|
fieldId: group.fieldId,
|
||||||
));
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BoardEditingRow {
|
||||||
|
String columnId;
|
||||||
|
RowPB row;
|
||||||
|
|
||||||
|
BoardEditingRow({
|
||||||
|
required this.columnId,
|
||||||
|
required this.row,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -60,6 +60,8 @@ class BoardContent extends StatefulWidget {
|
|||||||
|
|
||||||
class _BoardContentState extends State<BoardContent> {
|
class _BoardContentState extends State<BoardContent> {
|
||||||
late ScrollController scrollController;
|
late ScrollController scrollController;
|
||||||
|
late AFBoardScrollManager scrollManager;
|
||||||
|
|
||||||
final config = AFBoardConfig(
|
final config = AFBoardConfig(
|
||||||
columnBackgroundColor: HexColor.fromHex('#F7F8FC'),
|
columnBackgroundColor: HexColor.fromHex('#F7F8FC'),
|
||||||
);
|
);
|
||||||
@ -67,37 +69,55 @@ class _BoardContentState extends State<BoardContent> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
scrollController = ScrollController();
|
scrollController = ScrollController();
|
||||||
|
scrollManager = AFBoardScrollManager();
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<BoardBloc, BoardState>(
|
return BlocListener<BoardBloc, BoardState>(
|
||||||
buildWhen: (previous, current) =>
|
listener: (context, state) {
|
||||||
previous.groupIds.length != current.groupIds.length,
|
state.editingRow.fold(
|
||||||
builder: (context, state) {
|
() => null,
|
||||||
return Container(
|
(editingRow) {
|
||||||
color: Colors.white,
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
child: Padding(
|
scrollManager.scrollToBottom(editingRow.columnId, () {
|
||||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
|
context
|
||||||
child: AFBoard(
|
.read<BoardBloc>()
|
||||||
scrollController: scrollController,
|
.add(BoardEvent.endEditRow(editingRow.row.id));
|
||||||
dataController: context.read<BoardBloc>().boardController,
|
});
|
||||||
headerBuilder: _buildHeader,
|
});
|
||||||
footBuilder: _buildFooter,
|
},
|
||||||
cardBuilder: (_, column, columnItem) => _buildCard(
|
|
||||||
context,
|
|
||||||
column,
|
|
||||||
columnItem,
|
|
||||||
),
|
|
||||||
columnConstraints: const BoxConstraints.tightFor(width: 240),
|
|
||||||
config: AFBoardConfig(
|
|
||||||
columnBackgroundColor: HexColor.fromHex('#F7F8FC'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
child: BlocBuilder<BoardBloc, BoardState>(
|
||||||
|
buildWhen: (previous, current) =>
|
||||||
|
previous.groupIds.length != current.groupIds.length,
|
||||||
|
builder: (context, state) {
|
||||||
|
return Container(
|
||||||
|
color: Colors.white,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
|
||||||
|
child: AFBoard(
|
||||||
|
scrollManager: scrollManager,
|
||||||
|
scrollController: scrollController,
|
||||||
|
dataController: context.read<BoardBloc>().boardController,
|
||||||
|
headerBuilder: _buildHeader,
|
||||||
|
footBuilder: _buildFooter,
|
||||||
|
cardBuilder: (_, column, columnItem) => _buildCard(
|
||||||
|
context,
|
||||||
|
column,
|
||||||
|
columnItem,
|
||||||
|
),
|
||||||
|
columnConstraints: const BoxConstraints.tightFor(width: 240),
|
||||||
|
config: AFBoardConfig(
|
||||||
|
columnBackgroundColor: HexColor.fromHex('#F7F8FC'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +198,7 @@ class _BoardContentState extends State<BoardContent> {
|
|||||||
final cellBuilder = BoardCellBuilder(cardController);
|
final cellBuilder = BoardCellBuilder(cardController);
|
||||||
final isEditing = context.read<BoardBloc>().state.editingRow.fold(
|
final isEditing = context.read<BoardBloc>().state.editingRow.fold(
|
||||||
() => false,
|
() => false,
|
||||||
(editingRow) => editingRow.id == rowPB.id,
|
(editingRow) => editingRow.row.id == rowPB.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
return AppFlowyColumnItemCard(
|
return AppFlowyColumnItemCard(
|
||||||
|
@ -10,6 +10,16 @@ import 'reorder_flex/reorder_flex.dart';
|
|||||||
import 'reorder_phantom/phantom_controller.dart';
|
import 'reorder_phantom/phantom_controller.dart';
|
||||||
import '../rendering/board_overlay.dart';
|
import '../rendering/board_overlay.dart';
|
||||||
|
|
||||||
|
class AFBoardScrollManager {
|
||||||
|
BoardColumnState? _columnState;
|
||||||
|
|
||||||
|
// AFBoardScrollManager();
|
||||||
|
|
||||||
|
void scrollToBottom(String columnId, VoidCallback? completed) {
|
||||||
|
_columnState?.reorderFlexStateAtColumn(columnId)?.scrollToBottom(completed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class AFBoardConfig {
|
class AFBoardConfig {
|
||||||
final double cornerRadius;
|
final double cornerRadius;
|
||||||
final EdgeInsets columnPadding;
|
final EdgeInsets columnPadding;
|
||||||
@ -58,6 +68,10 @@ class AFBoard extends StatelessWidget {
|
|||||||
|
|
||||||
final AFBoardConfig config;
|
final AFBoardConfig config;
|
||||||
|
|
||||||
|
final AFBoardScrollManager? scrollManager;
|
||||||
|
|
||||||
|
final BoardColumnState _columnState = BoardColumnState();
|
||||||
|
|
||||||
AFBoard({
|
AFBoard({
|
||||||
required this.dataController,
|
required this.dataController,
|
||||||
required this.cardBuilder,
|
required this.cardBuilder,
|
||||||
@ -65,6 +79,7 @@ class AFBoard extends StatelessWidget {
|
|||||||
this.footBuilder,
|
this.footBuilder,
|
||||||
this.headerBuilder,
|
this.headerBuilder,
|
||||||
this.scrollController,
|
this.scrollController,
|
||||||
|
this.scrollManager,
|
||||||
this.columnConstraints = const BoxConstraints(maxWidth: 200),
|
this.columnConstraints = const BoxConstraints(maxWidth: 200),
|
||||||
this.config = const AFBoardConfig(),
|
this.config = const AFBoardConfig(),
|
||||||
Key? key,
|
Key? key,
|
||||||
@ -77,10 +92,16 @@ class AFBoard extends StatelessWidget {
|
|||||||
value: dataController,
|
value: dataController,
|
||||||
child: Consumer<AFBoardDataController>(
|
child: Consumer<AFBoardDataController>(
|
||||||
builder: (context, notifier, child) {
|
builder: (context, notifier, child) {
|
||||||
|
if (scrollManager != null) {
|
||||||
|
scrollManager!._columnState = _columnState;
|
||||||
|
}
|
||||||
|
|
||||||
return AFBoardContent(
|
return AFBoardContent(
|
||||||
config: config,
|
config: config,
|
||||||
dataController: dataController,
|
dataController: dataController,
|
||||||
scrollController: scrollController,
|
scrollController: scrollController,
|
||||||
|
scrollManager: scrollManager,
|
||||||
|
columnState: _columnState,
|
||||||
background: background,
|
background: background,
|
||||||
delegate: phantomController,
|
delegate: phantomController,
|
||||||
columnConstraints: columnConstraints,
|
columnConstraints: columnConstraints,
|
||||||
@ -106,6 +127,8 @@ class AFBoardContent extends StatefulWidget {
|
|||||||
final AFBoardConfig config;
|
final AFBoardConfig config;
|
||||||
final ReorderFlexConfig reorderFlexConfig;
|
final ReorderFlexConfig reorderFlexConfig;
|
||||||
final BoxConstraints columnConstraints;
|
final BoxConstraints columnConstraints;
|
||||||
|
final AFBoardScrollManager? scrollManager;
|
||||||
|
final BoardColumnState columnState;
|
||||||
|
|
||||||
///
|
///
|
||||||
final AFBoardColumnCardBuilder cardBuilder;
|
final AFBoardColumnCardBuilder cardBuilder;
|
||||||
@ -125,6 +148,8 @@ class AFBoardContent extends StatefulWidget {
|
|||||||
required this.onReorder,
|
required this.onReorder,
|
||||||
required this.delegate,
|
required this.delegate,
|
||||||
required this.dataController,
|
required this.dataController,
|
||||||
|
required this.scrollManager,
|
||||||
|
required this.columnState,
|
||||||
this.onDragStarted,
|
this.onDragStarted,
|
||||||
this.onDragEnded,
|
this.onDragEnded,
|
||||||
this.scrollController,
|
this.scrollController,
|
||||||
@ -143,22 +168,19 @@ class AFBoardContent extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _AFBoardContentState extends State<AFBoardContent> {
|
class _AFBoardContentState extends State<AFBoardContent> {
|
||||||
late _BoardColumnState columnState;
|
final GlobalKey _boardContentKey =
|
||||||
|
|
||||||
final GlobalKey _columnContainerOverlayKey =
|
|
||||||
GlobalKey(debugLabel: '$AFBoardContent overlay key');
|
GlobalKey(debugLabel: '$AFBoardContent overlay key');
|
||||||
late BoardOverlayEntry _overlayEntry;
|
late BoardOverlayEntry _overlayEntry;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
columnState = _BoardColumnState();
|
|
||||||
_overlayEntry = BoardOverlayEntry(
|
_overlayEntry = BoardOverlayEntry(
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
final interceptor = OverlappingDragTargetInterceptor(
|
final interceptor = OverlappingDragTargetInterceptor(
|
||||||
reorderFlexId: widget.dataController.identifier,
|
reorderFlexId: widget.dataController.identifier,
|
||||||
acceptedReorderFlexId: widget.dataController.columnIds,
|
acceptedReorderFlexId: widget.dataController.columnIds,
|
||||||
delegate: widget.delegate,
|
delegate: widget.delegate,
|
||||||
columnKeys: UnmodifiableMapView(columnState.columnKeys),
|
columnKeys: UnmodifiableMapView(widget.columnState.columnKeys),
|
||||||
);
|
);
|
||||||
|
|
||||||
final reorderFlex = ReorderFlex(
|
final reorderFlex = ReorderFlex(
|
||||||
@ -198,7 +220,7 @@ class _AFBoardContentState extends State<AFBoardContent> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BoardOverlay(
|
return BoardOverlay(
|
||||||
key: _columnContainerOverlayKey,
|
key: _boardContentKey,
|
||||||
initialEntries: [_overlayEntry],
|
initialEntries: [_overlayEntry],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -220,6 +242,8 @@ class _AFBoardContentState extends State<AFBoardContent> {
|
|||||||
value: widget.dataController.getColumnController(columnData.id),
|
value: widget.dataController.getColumnController(columnData.id),
|
||||||
child: Consumer<AFBoardColumnDataController>(
|
child: Consumer<AFBoardColumnDataController>(
|
||||||
builder: (context, value, child) {
|
builder: (context, value, child) {
|
||||||
|
final scrollController =
|
||||||
|
widget.columnState.scrollController(columnData.id);
|
||||||
final boardColumn = AFBoardColumnWidget(
|
final boardColumn = AFBoardColumnWidget(
|
||||||
key: ValueKey(columnData.id),
|
key: ValueKey(columnData.id),
|
||||||
margin: _marginFromIndex(columnIndex),
|
margin: _marginFromIndex(columnIndex),
|
||||||
@ -228,14 +252,17 @@ class _AFBoardContentState extends State<AFBoardContent> {
|
|||||||
footBuilder: widget.footBuilder,
|
footBuilder: widget.footBuilder,
|
||||||
cardBuilder: widget.cardBuilder,
|
cardBuilder: widget.cardBuilder,
|
||||||
dataSource: dataSource,
|
dataSource: dataSource,
|
||||||
scrollController: columnState.scrollController(columnData.id),
|
scrollController: scrollController,
|
||||||
phantomController: widget.phantomController,
|
phantomController: widget.phantomController,
|
||||||
onReorder: widget.dataController.moveColumnItem,
|
onReorder: widget.dataController.moveColumnItem,
|
||||||
cornerRadius: widget.config.cornerRadius,
|
cornerRadius: widget.config.cornerRadius,
|
||||||
backgroundColor: widget.config.columnBackgroundColor,
|
backgroundColor: widget.config.columnBackgroundColor,
|
||||||
);
|
);
|
||||||
|
|
||||||
columnState.cacheColumn(columnData.id, boardColumn.globalKey);
|
widget.columnState.addColumn(
|
||||||
|
columnData.id,
|
||||||
|
boardColumn.globalKey,
|
||||||
|
);
|
||||||
|
|
||||||
return ConstrainedBox(
|
return ConstrainedBox(
|
||||||
constraints: widget.columnConstraints,
|
constraints: widget.columnConstraints,
|
||||||
@ -297,25 +324,36 @@ class _BoardColumnDataSourceImpl extends AFBoardColumnDataDataSource {
|
|||||||
List<String> get acceptedColumnIds => dataController.columnIds;
|
List<String> get acceptedColumnIds => dataController.columnIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _BoardColumnState {
|
class BoardColumnState {
|
||||||
|
/// Quick access to the [AFBoardColumnWidget]
|
||||||
final Map<String, GlobalKey> columnKeys = {};
|
final Map<String, GlobalKey> columnKeys = {};
|
||||||
|
|
||||||
void cacheColumn(String columnId, GlobalKey key) {
|
/// Records the position of the [AFBoardColumnWidget]
|
||||||
|
final Map<String, ScrollPosition> columnScrollPositions = {};
|
||||||
|
|
||||||
|
void addColumn(String columnId, GlobalKey key) {
|
||||||
columnKeys[columnId] = key;
|
columnKeys[columnId] = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollController scrollController(String columnId) {
|
ReorderFlexState? reorderFlexStateAtColumn(String columnId) {
|
||||||
final flexGlobalKey = columnKeys[columnId];
|
final flexGlobalKey = columnKeys[columnId];
|
||||||
var scrollController = ScrollController();
|
if (flexGlobalKey == null) return null;
|
||||||
if (flexGlobalKey != null) {
|
if (flexGlobalKey.currentState is! ReorderFlexState) return null;
|
||||||
// assert(flexGlobalKey.currentWidget is ReorderFlex);
|
final state = flexGlobalKey.currentState as ReorderFlexState;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReorderFlex? reorderFlexAtColumn(String columnId) {
|
||||||
|
final flexGlobalKey = columnKeys[columnId];
|
||||||
|
if (flexGlobalKey == null) return null;
|
||||||
|
if (flexGlobalKey.currentWidget is! ReorderFlex) return null;
|
||||||
|
final widget = flexGlobalKey.currentWidget as ReorderFlex;
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollController scrollController(String columnId) {
|
||||||
|
ScrollController scrollController = ScrollController();
|
||||||
|
|
||||||
// if (flexGlobalKey.currentWidget is ReorderFlex) {
|
|
||||||
// final reorderFlex = flexGlobalKey.currentWidget as ReorderFlex;
|
|
||||||
// final offset = reorderFlex.scrollController!.offset;
|
|
||||||
// scrollController = ScrollController(initialScrollOffset: offset);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
return scrollController;
|
return scrollController;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,13 +116,10 @@ class _AFBoardColumnWidgetState extends State<AFBoardColumnWidget> {
|
|||||||
final GlobalKey _columnOverlayKey =
|
final GlobalKey _columnOverlayKey =
|
||||||
GlobalKey(debugLabel: '$AFBoardColumnWidget overlay key');
|
GlobalKey(debugLabel: '$AFBoardColumnWidget overlay key');
|
||||||
|
|
||||||
late GlobalObjectKey _indexGlobalKey;
|
|
||||||
|
|
||||||
late BoardOverlayEntry _overlayEntry;
|
late BoardOverlayEntry _overlayEntry;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_indexGlobalKey = GlobalObjectKey(widget.key!);
|
|
||||||
_overlayEntry = BoardOverlayEntry(
|
_overlayEntry = BoardOverlayEntry(
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
final children = widget.dataSource.columnData.items
|
final children = widget.dataSource.columnData.items
|
||||||
@ -143,6 +140,7 @@ class _AFBoardColumnWidgetState extends State<AFBoardColumnWidget> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Widget reorderFlex = ReorderFlex(
|
Widget reorderFlex = ReorderFlex(
|
||||||
|
key: widget.globalKey,
|
||||||
scrollController: widget.scrollController,
|
scrollController: widget.scrollController,
|
||||||
config: widget.config,
|
config: widget.config,
|
||||||
onDragStarted: (index) {
|
onDragStarted: (index) {
|
||||||
@ -165,8 +163,6 @@ class _AFBoardColumnWidgetState extends State<AFBoardColumnWidget> {
|
|||||||
children: children,
|
children: children,
|
||||||
);
|
);
|
||||||
|
|
||||||
reorderFlex = KeyedSubtree(key: _indexGlobalKey, child: reorderFlex);
|
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
margin: widget.margin,
|
margin: widget.margin,
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
|
@ -177,9 +177,6 @@ class ReorderFlexState extends State<ReorderFlex>
|
|||||||
// ));
|
// ));
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
Future.delayed(Duration(seconds: 3), () {
|
|
||||||
scrollToBottom();
|
|
||||||
});
|
|
||||||
|
|
||||||
final child = _wrapContainer(children);
|
final child = _wrapContainer(children);
|
||||||
return _wrapScrollView(child: child);
|
return _wrapScrollView(child: child);
|
||||||
@ -532,17 +529,25 @@ class ReorderFlexState extends State<ReorderFlex>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scrollToBottom() {
|
void scrollToBottom(VoidCallback? completed) {
|
||||||
if (_scrolling) return;
|
if (_scrolling) {
|
||||||
|
completed?.call();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (widget.dataSource.items.isNotEmpty) {
|
if (widget.dataSource.items.isNotEmpty) {
|
||||||
final item = widget.dataSource.items.last;
|
final item = widget.dataSource.items.last;
|
||||||
final indexKey = _childKeys[item.id];
|
final indexKey = _childKeys[item.id];
|
||||||
if (indexKey == null) return;
|
if (indexKey == null) {
|
||||||
|
completed?.call();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final indexContext = indexKey.currentContext;
|
final indexContext = indexKey.currentContext;
|
||||||
if (indexContext == null) return;
|
if (indexContext == null || _scrollController.hasClients == false) {
|
||||||
if (_scrollController.hasClients == false) return;
|
completed?.call();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final renderObject = indexContext.findRenderObject();
|
final renderObject = indexContext.findRenderObject();
|
||||||
if (renderObject != null) {
|
if (renderObject != null) {
|
||||||
@ -554,8 +559,13 @@ class ReorderFlexState extends State<ReorderFlex>
|
|||||||
duration: const Duration(milliseconds: 120),
|
duration: const Duration(milliseconds: 120),
|
||||||
)
|
)
|
||||||
.then((value) {
|
.then((value) {
|
||||||
setState(() => _scrolling = false);
|
setState(() {
|
||||||
|
_scrolling = false;
|
||||||
|
completed?.call();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
completed?.call();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user