Skip to content

Commit c7b671c

Browse files
authored
Merge pull request #895 from AppFlowy-IO/feat/board_move_card_animation
Feat/board move card animation
2 parents 9395eb2 + 2152bb7 commit c7b671c

File tree

13 files changed

+195
-82
lines changed

13 files changed

+195
-82
lines changed

frontend/app_flowy/packages/appflowy_board/CHANGELOG.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
1+
# 0.0.5
2+
* Optimize insert card animation
3+
* Enable insert card at the end of the column
4+
* Fix some bugs
5+
16
# 0.0.4
2-
* fix some bugs
7+
* Fix some bugs
38

49
# 0.0.3
510
* Support customize UI
611
* Update example
712
* Add AppFlowy style widget
813

9-
## 0.0.2
14+
# 0.0.2
1015

1116
* Update documentation
1217

13-
## 0.0.1
18+
# 0.0.1
1419

1520
* Support drag and drop column
1621
* Support drag and drop column items from one to another

frontend/app_flowy/packages/appflowy_board/example/lib/multi_board_list_example.dart

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,18 @@ class _MultiBoardListExampleState extends State<MultiBoardListExample> {
2626
List<AFColumnItem> a = [
2727
TextItem("Card 1"),
2828
TextItem("Card 2"),
29-
// RichTextItem(title: "Card 3", subtitle: 'Aug 1, 2020 4:05 PM'),
29+
RichTextItem(title: "Card 3", subtitle: 'Aug 1, 2020 4:05 PM'),
3030
TextItem("Card 4"),
31+
TextItem("Card 5"),
32+
TextItem("Card 6"),
33+
RichTextItem(title: "Card 7", subtitle: 'Aug 1, 2020 4:05 PM'),
34+
RichTextItem(title: "Card 8", subtitle: 'Aug 1, 2020 4:05 PM'),
35+
TextItem("Card 9"),
3136
];
3237
final column1 = AFBoardColumnData(id: "To Do", items: a);
3338
final column2 = AFBoardColumnData(id: "In Progress", items: <AFColumnItem>[
34-
// RichTextItem(title: "Card 5", subtitle: 'Aug 1, 2020 4:05 PM'),
35-
// TextItem("Card 6"),
39+
RichTextItem(title: "Card 10", subtitle: 'Aug 1, 2020 4:05 PM'),
40+
TextItem("Card 11"),
3641
]);
3742

3843
final column3 = AFBoardColumnData(id: "Done", items: <AFColumnItem>[]);
@@ -93,7 +98,7 @@ class _MultiBoardListExampleState extends State<MultiBoardListExample> {
9398
return Align(
9499
alignment: Alignment.centerLeft,
95100
child: Padding(
96-
padding: const EdgeInsets.symmetric(horizontal: 20),
101+
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 40),
97102
child: Text(item.s),
98103
),
99104
);

frontend/app_flowy/packages/appflowy_board/lib/src/utils/log.dart

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import 'package:flutter/material.dart';
44
const DART_LOG = "Dart_LOG";
55

66
class Log {
7-
// static const enableLog = bool.hasEnvironment(DART_LOG);
8-
// static final shared = Log();
97
static const enableLog = false;
108

119
static void info(String? message) {
@@ -16,19 +14,19 @@ class Log {
1614

1715
static void debug(String? message) {
1816
if (enableLog) {
19-
debugPrint('🐛[Debug]=> $message');
17+
debugPrint('🐛[Debug] - ${DateTime.now().second}=> $message');
2018
}
2119
}
2220

2321
static void warn(String? message) {
2422
if (enableLog) {
25-
debugPrint('🐛[Warn]=> $message');
23+
debugPrint('🐛[Warn] - ${DateTime.now().second} => $message');
2624
}
2725
}
2826

2927
static void trace(String? message) {
3028
if (enableLog) {
31-
// debugPrint('❗️[Trace]=> $message');
29+
debugPrint('❗️[Trace] - ${DateTime.now().second}=> $message');
3230
}
3331
}
3432
}

frontend/app_flowy/packages/appflowy_board/lib/src/widgets/board.dart

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ class _BoardContentState extends State<BoardContent> {
159159
dataSource: widget.dataController,
160160
direction: Axis.horizontal,
161161
interceptor: interceptor,
162-
children: _buildColumns(),
162+
children: _buildColumns(interceptor.columnKeys),
163163
);
164164

165165
return Stack(
@@ -191,7 +191,7 @@ class _BoardContentState extends State<BoardContent> {
191191
);
192192
}
193193

194-
List<Widget> _buildColumns() {
194+
List<Widget> _buildColumns(List<ColumnKey> columnKeys) {
195195
final List<Widget> children =
196196
widget.dataController.columnDatas.asMap().entries.map(
197197
(item) {
@@ -208,21 +208,33 @@ class _BoardContentState extends State<BoardContent> {
208208
value: widget.dataController.columnController(columnData.id),
209209
child: Consumer<AFBoardColumnDataController>(
210210
builder: (context, value, child) {
211+
final boardColumn = AFBoardColumnWidget(
212+
margin: _marginFromIndex(columnIndex),
213+
itemMargin: widget.config.columnItemPadding,
214+
headerBuilder: widget.headerBuilder,
215+
footBuilder: widget.footBuilder,
216+
cardBuilder: widget.cardBuilder,
217+
dataSource: dataSource,
218+
scrollController: ScrollController(),
219+
phantomController: widget.phantomController,
220+
onReorder: widget.dataController.moveColumnItem,
221+
cornerRadius: widget.config.cornerRadius,
222+
backgroundColor: widget.config.columnBackgroundColor,
223+
);
224+
225+
// columnKeys
226+
// .removeWhere((element) => element.columnId == columnData.id);
227+
228+
// columnKeys.add(
229+
// ColumnKey(
230+
// columnId: columnData.id,
231+
// key: boardColumn.columnGlobalKey,
232+
// ),
233+
// );
234+
211235
return ConstrainedBox(
212236
constraints: widget.columnConstraints,
213-
child: AFBoardColumnWidget(
214-
margin: _marginFromIndex(columnIndex),
215-
itemMargin: widget.config.columnItemPadding,
216-
headerBuilder: widget.headerBuilder,
217-
footBuilder: widget.footBuilder,
218-
cardBuilder: widget.cardBuilder,
219-
dataSource: dataSource,
220-
scrollController: ScrollController(),
221-
phantomController: widget.phantomController,
222-
onReorder: widget.dataController.moveColumnItem,
223-
cornerRadius: widget.config.cornerRadius,
224-
backgroundColor: widget.config.columnBackgroundColor,
225-
),
237+
child: boardColumn,
226238
);
227239
},
228240
),

frontend/app_flowy/packages/appflowy_board/lib/src/widgets/board_column/board_column.dart

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ class AFBoardColumnWidget extends StatefulWidget {
8787

8888
final Color backgroundColor;
8989

90-
const AFBoardColumnWidget({
90+
final GlobalKey columnGlobalKey = GlobalKey();
91+
92+
AFBoardColumnWidget({
9193
Key? key,
9294
this.headerBuilder,
9395
this.footBuilder,
@@ -136,8 +138,8 @@ class _AFBoardColumnWidgetState extends State<AFBoardColumnWidget> {
136138
draggableTargetBuilder: PhantomDraggableBuilder(),
137139
);
138140

139-
final reorderFlex = ReorderFlex(
140-
key: widget.key,
141+
Widget reorderFlex = ReorderFlex(
142+
key: widget.columnGlobalKey,
141143
scrollController: widget.scrollController,
142144
config: widget.config,
143145
onDragStarted: (index) {
@@ -160,6 +162,9 @@ class _AFBoardColumnWidgetState extends State<AFBoardColumnWidget> {
160162
children: children,
161163
);
162164

165+
// reorderFlex =
166+
// KeyedSubtree(key: widget.columnGlobalKey, child: reorderFlex);
167+
163168
return Container(
164169
margin: widget.margin,
165170
clipBehavior: Clip.hardEdge,

frontend/app_flowy/packages/appflowy_board/lib/src/widgets/board_data.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,8 @@ class AFBoardDataController extends ChangeNotifier
197197
assert(index != -1);
198198
if (index != -1) {
199199
if (index != newIndex) {
200-
// Log.debug('[$BoardPhantomController] update $toColumnId:$index to $toColumnId:$phantomIndex');
200+
Log.trace(
201+
'[$BoardPhantomController] update $columnId:$index to $columnId:$newIndex');
201202
final item = columnDataController.removeAt(index, notify: false);
202203
columnDataController.insert(newIndex, item, notify: false);
203204
}

frontend/app_flowy/packages/appflowy_board/lib/src/widgets/reorder_flex/drag_state.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class FlexDragTargetData extends DragTargetData {
4343
}
4444

4545
class DraggingState {
46-
final String id;
46+
final String reorderFlexId;
4747

4848
/// The member of widget.children currently being dragged.
4949
Widget? _draggingWidget;
@@ -72,7 +72,7 @@ class DraggingState {
7272
/// The additional margin to place around a computed drop area.
7373
static const double _dropAreaMargin = 0.0;
7474

75-
DraggingState(this.id);
75+
DraggingState(this.reorderFlexId);
7676

7777
Size get dropAreaSize {
7878
if (feedbackSize == null) {
@@ -132,7 +132,7 @@ class DraggingState {
132132
}
133133

134134
void updateNextIndex(int index) {
135-
Log.trace('updateNextIndex: $index');
135+
Log.debug('$reorderFlexId updateNextIndex: $index');
136136
nextIndex = index;
137137
}
138138

frontend/app_flowy/packages/appflowy_board/lib/src/widgets/reorder_flex/drag_target.dart

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,10 @@ class DragTargetAnimation {
222222
value: 0, vsync: vsync, duration: reorderAnimationDuration);
223223

224224
insertController = AnimationController(
225-
value: 0.0, vsync: vsync, duration: const Duration(milliseconds: 100));
225+
value: 0.0, vsync: vsync, duration: const Duration(milliseconds: 200));
226226

227227
deleteController = AnimationController(
228-
value: 0.0, vsync: vsync, duration: const Duration(milliseconds: 10));
228+
value: 0.0, vsync: vsync, duration: const Duration(milliseconds: 1));
229229
}
230230

231231
void startDragging() {
@@ -276,6 +276,31 @@ class IgnorePointerWidget extends StatelessWidget {
276276
}
277277
}
278278

279+
class AbsorbPointerWidget extends StatelessWidget {
280+
final Widget? child;
281+
final bool useIntrinsicSize;
282+
const AbsorbPointerWidget({
283+
required this.child,
284+
this.useIntrinsicSize = false,
285+
Key? key,
286+
}) : super(key: key);
287+
288+
@override
289+
Widget build(BuildContext context) {
290+
final sizedChild = useIntrinsicSize
291+
? child
292+
: SizedBox(width: 0.0, height: 0.0, child: child);
293+
294+
final opacity = useIntrinsicSize ? 0.3 : 0.0;
295+
return AbsorbPointer(
296+
child: Opacity(
297+
opacity: opacity,
298+
child: sizedChild,
299+
),
300+
);
301+
}
302+
}
303+
279304
class PhantomWidget extends StatelessWidget {
280305
final Widget? child;
281306
final double opacity;
@@ -371,6 +396,7 @@ class _DragTargeMovePlaceholderState extends State<DragTargeMovePlaceholder> {
371396
}
372397

373398
abstract class FakeDragTargetEventTrigger {
399+
void fakeOnDragStart(void Function(int?) callback);
374400
void fakeOnDragEnded(VoidCallback callback);
375401
}
376402

@@ -421,6 +447,10 @@ class _FakeDragTargetState<T extends DragTargetData>
421447
/// Start insert animation
422448
widget.insertAnimationController.forward(from: 0.0);
423449

450+
// widget.eventTrigger.fakeOnDragStart((insertIndex) {
451+
// Log.trace("[$FakeDragTarget] on drag $insertIndex");
452+
// });
453+
424454
widget.eventTrigger.fakeOnDragEnded(() {
425455
WidgetsBinding.instance.addPostFrameCallback((_) {
426456
widget.onDragEnded(widget.eventData.dragTargetData as T);
@@ -436,15 +466,15 @@ class _FakeDragTargetState<T extends DragTargetData>
436466
return SizeTransitionWithIntrinsicSize(
437467
sizeFactor: widget.deleteAnimationController,
438468
axis: Axis.vertical,
439-
child: IgnorePointerWidget(
469+
child: AbsorbPointerWidget(
440470
child: widget.child,
441471
),
442472
);
443473
} else {
444474
return SizeTransitionWithIntrinsicSize(
445475
sizeFactor: widget.insertAnimationController,
446476
axis: Axis.vertical,
447-
child: IgnorePointerWidget(
477+
child: AbsorbPointerWidget(
448478
useIntrinsicSize: true,
449479
child: widget.child,
450480
),

0 commit comments

Comments
 (0)