mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: create board card
This commit is contained in:
parent
b7d71428be
commit
bc346dfd67
@ -14,12 +14,14 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'board_data_controller.dart';
|
import 'board_data_controller.dart';
|
||||||
|
import 'group_controller.dart';
|
||||||
|
|
||||||
part 'board_bloc.freezed.dart';
|
part 'board_bloc.freezed.dart';
|
||||||
|
|
||||||
class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||||
final BoardDataController _dataController;
|
final BoardDataController _dataController;
|
||||||
late final AFBoardDataController boardDataController;
|
late final AFBoardDataController afBoardDataController;
|
||||||
|
List<GroupController> groupControllers = [];
|
||||||
|
|
||||||
GridFieldCache get fieldCache => _dataController.fieldCache;
|
GridFieldCache get fieldCache => _dataController.fieldCache;
|
||||||
String get gridId => _dataController.gridId;
|
String get gridId => _dataController.gridId;
|
||||||
@ -27,7 +29,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
BoardBloc({required ViewPB view})
|
BoardBloc({required ViewPB view})
|
||||||
: _dataController = BoardDataController(view: view),
|
: _dataController = BoardDataController(view: view),
|
||||||
super(BoardState.initial(view.id)) {
|
super(BoardState.initial(view.id)) {
|
||||||
boardDataController = AFBoardDataController(
|
afBoardDataController = AFBoardDataController(
|
||||||
onMoveColumn: (
|
onMoveColumn: (
|
||||||
fromIndex,
|
fromIndex,
|
||||||
toIndex,
|
toIndex,
|
||||||
@ -71,9 +73,6 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
didReceiveGridUpdate: (GridPB grid) {
|
didReceiveGridUpdate: (GridPB grid) {
|
||||||
emit(state.copyWith(grid: Some(grid)));
|
emit(state.copyWith(grid: Some(grid)));
|
||||||
},
|
},
|
||||||
didReceiveGroups: (List<GroupPB> groups) {
|
|
||||||
emit(state.copyWith(groups: groups));
|
|
||||||
},
|
|
||||||
didReceiveRows: (List<RowInfo> rowInfos) {
|
didReceiveRows: (List<RowInfo> rowInfos) {
|
||||||
emit(state.copyWith(rowInfos: rowInfos));
|
emit(state.copyWith(rowInfos: rowInfos));
|
||||||
},
|
},
|
||||||
@ -85,9 +84,24 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
await _dataController.dispose();
|
await _dataController.dispose();
|
||||||
|
for (final controller in groupControllers) {
|
||||||
|
controller.dispose();
|
||||||
|
}
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void initializeGroups(List<GroupPB> groups) {
|
||||||
|
for (final group in groups) {
|
||||||
|
final delegate = GroupControllerDelegateImpl(afBoardDataController);
|
||||||
|
final controller = GroupController(
|
||||||
|
group: group,
|
||||||
|
delegate: delegate,
|
||||||
|
);
|
||||||
|
controller.startListening();
|
||||||
|
groupControllers.add(controller);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GridRowCache? getRowCache(String blockId) {
|
GridRowCache? getRowCache(String blockId) {
|
||||||
final GridBlockCache? blockCache = _dataController.blocks[blockId];
|
final GridBlockCache? blockCache = _dataController.blocks[blockId];
|
||||||
return blockCache?.rowCache;
|
return blockCache?.rowCache;
|
||||||
@ -100,7 +114,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
add(BoardEvent.didReceiveGridUpdate(grid));
|
add(BoardEvent.didReceiveGridUpdate(grid));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onGroupChanged: (groups) {
|
didLoadGroups: (groups) {
|
||||||
List<AFBoardColumnData> columns = groups.map((group) {
|
List<AFBoardColumnData> columns = groups.map((group) {
|
||||||
return AFBoardColumnData(
|
return AFBoardColumnData(
|
||||||
id: group.groupId,
|
id: group.groupId,
|
||||||
@ -110,7 +124,8 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
boardDataController.addColumns(columns);
|
afBoardDataController.addColumns(columns);
|
||||||
|
initializeGroups(groups);
|
||||||
},
|
},
|
||||||
onRowsChanged: (List<RowInfo> rowInfos, RowsChangedReason reason) {
|
onRowsChanged: (List<RowInfo> rowInfos, RowsChangedReason reason) {
|
||||||
add(BoardEvent.didReceiveRows(rowInfos));
|
add(BoardEvent.didReceiveRows(rowInfos));
|
||||||
@ -155,8 +170,6 @@ class BoardEvent with _$BoardEvent {
|
|||||||
const factory BoardEvent.initial() = InitialGrid;
|
const factory BoardEvent.initial() = InitialGrid;
|
||||||
const factory BoardEvent.createRow(String groupId) = _CreateRow;
|
const factory BoardEvent.createRow(String groupId) = _CreateRow;
|
||||||
const factory BoardEvent.endEditRow(String rowId) = _EndEditRow;
|
const factory BoardEvent.endEditRow(String rowId) = _EndEditRow;
|
||||||
const factory BoardEvent.didReceiveGroups(List<GroupPB> groups) =
|
|
||||||
_DidReceiveGroup;
|
|
||||||
const factory BoardEvent.didReceiveRows(List<RowInfo> rowInfos) =
|
const factory BoardEvent.didReceiveRows(List<RowInfo> rowInfos) =
|
||||||
_DidReceiveRows;
|
_DidReceiveRows;
|
||||||
const factory BoardEvent.didReceiveGridUpdate(
|
const factory BoardEvent.didReceiveGridUpdate(
|
||||||
@ -169,7 +182,6 @@ class BoardState with _$BoardState {
|
|||||||
const factory BoardState({
|
const factory BoardState({
|
||||||
required String gridId,
|
required String gridId,
|
||||||
required Option<GridPB> grid,
|
required Option<GridPB> grid,
|
||||||
required List<GroupPB> groups,
|
|
||||||
required Option<RowPB> editingRow,
|
required Option<RowPB> editingRow,
|
||||||
required List<RowInfo> rowInfos,
|
required List<RowInfo> rowInfos,
|
||||||
required GridLoadingState loadingState,
|
required GridLoadingState loadingState,
|
||||||
@ -177,7 +189,6 @@ class BoardState with _$BoardState {
|
|||||||
|
|
||||||
factory BoardState.initial(String gridId) => BoardState(
|
factory BoardState.initial(String gridId) => BoardState(
|
||||||
rowInfos: [],
|
rowInfos: [],
|
||||||
groups: [],
|
|
||||||
grid: none(),
|
grid: none(),
|
||||||
gridId: gridId,
|
gridId: gridId,
|
||||||
editingRow: none(),
|
editingRow: none(),
|
||||||
@ -228,3 +239,27 @@ class CreateCardItem extends AFColumnItem {
|
|||||||
@override
|
@override
|
||||||
String get id => '$CreateCardItem';
|
String get id => '$CreateCardItem';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GroupControllerDelegateImpl extends GroupControllerDelegate {
|
||||||
|
final AFBoardDataController controller;
|
||||||
|
|
||||||
|
GroupControllerDelegateImpl(this.controller);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void insertRow(String groupId, RowPB row, int? index) {
|
||||||
|
final item = BoardColumnItem(row: row);
|
||||||
|
if (index != null) {
|
||||||
|
controller.insertColumnItem(groupId, index, item);
|
||||||
|
} else {
|
||||||
|
controller.addColumnItem(groupId, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void removeRow(String groupId, String rowId) {
|
||||||
|
controller.removeColumnItem(groupId, rowId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void updateRow(String groupId, RowPB row) {}
|
||||||
|
}
|
||||||
|
@ -12,7 +12,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
|
|||||||
|
|
||||||
typedef OnFieldsChanged = void Function(UnmodifiableListView<FieldPB>);
|
typedef OnFieldsChanged = void Function(UnmodifiableListView<FieldPB>);
|
||||||
typedef OnGridChanged = void Function(GridPB);
|
typedef OnGridChanged = void Function(GridPB);
|
||||||
typedef OnGroupChanged = void Function(List<GroupPB>);
|
typedef DidLoadGroups = void Function(List<GroupPB>);
|
||||||
typedef OnRowsChanged = void Function(
|
typedef OnRowsChanged = void Function(
|
||||||
List<RowInfo>,
|
List<RowInfo>,
|
||||||
RowsChangedReason,
|
RowsChangedReason,
|
||||||
@ -30,7 +30,7 @@ class BoardDataController {
|
|||||||
|
|
||||||
OnFieldsChanged? _onFieldsChanged;
|
OnFieldsChanged? _onFieldsChanged;
|
||||||
OnGridChanged? _onGridChanged;
|
OnGridChanged? _onGridChanged;
|
||||||
OnGroupChanged? _onGroupChanged;
|
DidLoadGroups? _didLoadGroup;
|
||||||
OnRowsChanged? _onRowsChanged;
|
OnRowsChanged? _onRowsChanged;
|
||||||
OnError? _onError;
|
OnError? _onError;
|
||||||
|
|
||||||
@ -51,13 +51,13 @@ class BoardDataController {
|
|||||||
void addListener({
|
void addListener({
|
||||||
OnGridChanged? onGridChanged,
|
OnGridChanged? onGridChanged,
|
||||||
OnFieldsChanged? onFieldsChanged,
|
OnFieldsChanged? onFieldsChanged,
|
||||||
OnGroupChanged? onGroupChanged,
|
DidLoadGroups? didLoadGroups,
|
||||||
OnRowsChanged? onRowsChanged,
|
OnRowsChanged? onRowsChanged,
|
||||||
OnError? onError,
|
OnError? onError,
|
||||||
}) {
|
}) {
|
||||||
_onGridChanged = onGridChanged;
|
_onGridChanged = onGridChanged;
|
||||||
_onFieldsChanged = onFieldsChanged;
|
_onFieldsChanged = onFieldsChanged;
|
||||||
_onGroupChanged = onGroupChanged;
|
_didLoadGroup = didLoadGroups;
|
||||||
_onRowsChanged = onRowsChanged;
|
_onRowsChanged = onRowsChanged;
|
||||||
_onError = onError;
|
_onError = onError;
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ class BoardDataController {
|
|||||||
return Future(
|
return Future(
|
||||||
() => result.fold(
|
() => result.fold(
|
||||||
(groups) {
|
(groups) {
|
||||||
_onGroupChanged?.call(groups.items);
|
_didLoadGroup?.call(groups.items);
|
||||||
},
|
},
|
||||||
(err) => _onError?.call(err),
|
(err) => _onError?.call(err),
|
||||||
),
|
),
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
import 'package:flowy_sdk/log.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
|
||||||
|
|
||||||
|
import 'group_listener.dart';
|
||||||
|
|
||||||
|
abstract class GroupControllerDelegate {
|
||||||
|
void removeRow(String groupId, String rowId);
|
||||||
|
void insertRow(String groupId, RowPB row, int? index);
|
||||||
|
void updateRow(String groupId, RowPB row);
|
||||||
|
}
|
||||||
|
|
||||||
|
class GroupController {
|
||||||
|
final GroupPB group;
|
||||||
|
final GroupListener _listener;
|
||||||
|
final GroupControllerDelegate delegate;
|
||||||
|
|
||||||
|
GroupController({required this.group, required this.delegate})
|
||||||
|
: _listener = GroupListener(group);
|
||||||
|
|
||||||
|
void startListening() {
|
||||||
|
_listener.start(onGroupChanged: (result) {
|
||||||
|
result.fold(
|
||||||
|
(GroupRowsChangesetPB changeset) {
|
||||||
|
for (final insertedRow in changeset.insertedRows) {
|
||||||
|
final index = insertedRow.hasIndex() ? insertedRow.index : null;
|
||||||
|
delegate.insertRow(
|
||||||
|
group.groupId,
|
||||||
|
insertedRow.row,
|
||||||
|
index,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final deletedRow in changeset.deletedRows) {
|
||||||
|
delegate.removeRow(group.groupId, deletedRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final updatedRow in changeset.updatedRows) {
|
||||||
|
delegate.updateRow(group.groupId, updatedRow);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(err) => Log.error(err),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> dispose() async {
|
||||||
|
_listener.stop();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:app_flowy/core/grid_notification.dart';
|
||||||
|
import 'package:flowy_infra/notifier.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/group.pb.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/group_changeset.pb.dart';
|
||||||
|
|
||||||
|
typedef UpdateGroupNotifiedValue = Either<GroupRowsChangesetPB, FlowyError>;
|
||||||
|
|
||||||
|
class GroupListener {
|
||||||
|
final GroupPB group;
|
||||||
|
PublishNotifier<UpdateGroupNotifiedValue>? _groupNotifier = PublishNotifier();
|
||||||
|
GridNotificationListener? _listener;
|
||||||
|
GroupListener(this.group);
|
||||||
|
|
||||||
|
void start({
|
||||||
|
required void Function(UpdateGroupNotifiedValue) onGroupChanged,
|
||||||
|
}) {
|
||||||
|
_groupNotifier?.addPublishListener(onGroupChanged);
|
||||||
|
_listener = GridNotificationListener(
|
||||||
|
objectId: group.groupId,
|
||||||
|
handler: _handler,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handler(
|
||||||
|
GridNotification ty,
|
||||||
|
Either<Uint8List, FlowyError> result,
|
||||||
|
) {
|
||||||
|
switch (ty) {
|
||||||
|
case GridNotification.DidUpdateGroup:
|
||||||
|
result.fold(
|
||||||
|
(payload) => _groupNotifier?.value =
|
||||||
|
left(GroupRowsChangesetPB.fromBuffer(payload)),
|
||||||
|
(error) => _groupNotifier?.value = right(error),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> stop() async {
|
||||||
|
await _listener?.stop();
|
||||||
|
_groupNotifier?.dispose();
|
||||||
|
_groupNotifier = null;
|
||||||
|
}
|
||||||
|
}
|
@ -55,7 +55,7 @@ class BoardContent extends StatelessWidget {
|
|||||||
child: AFBoard(
|
child: AFBoard(
|
||||||
// key: UniqueKey(),
|
// key: UniqueKey(),
|
||||||
scrollController: ScrollController(),
|
scrollController: ScrollController(),
|
||||||
dataController: context.read<BoardBloc>().boardDataController,
|
dataController: context.read<BoardBloc>().afBoardDataController,
|
||||||
headerBuilder: _buildHeader,
|
headerBuilder: _buildHeader,
|
||||||
footBuilder: _buildFooter,
|
footBuilder: _buildFooter,
|
||||||
cardBuilder: (_, data) => _buildCard(context, data),
|
cardBuilder: (_, data) => _buildCard(context, data),
|
||||||
|
@ -23,9 +23,9 @@ class GridFFIService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<RowPB, FlowyError>> createRow({Option<String>? startRowId}) {
|
Future<Either<RowPB, FlowyError>> createRow({Option<String>? startRowId}) {
|
||||||
CreateRowPayloadPB payload = CreateRowPayloadPB.create()..gridId = gridId;
|
var payload = CreateTableRowPayloadPB.create()..gridId = gridId;
|
||||||
startRowId?.fold(() => null, (id) => payload.startRowId = id);
|
startRowId?.fold(() => null, (id) => payload.startRowId = id);
|
||||||
return GridEventCreateRow(payload).send();
|
return GridEventCreateTableRow(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<RowPB, FlowyError>> createBoardCard(String groupId) {
|
Future<Either<RowPB, FlowyError>> createBoardCard(String groupId) {
|
||||||
|
@ -15,11 +15,11 @@ class RowFFIService {
|
|||||||
{required this.gridId, required this.blockId, required this.rowId});
|
{required this.gridId, required this.blockId, required this.rowId});
|
||||||
|
|
||||||
Future<Either<RowPB, FlowyError>> createRow() {
|
Future<Either<RowPB, FlowyError>> createRow() {
|
||||||
CreateRowPayloadPB payload = CreateRowPayloadPB.create()
|
final payload = CreateTableRowPayloadPB.create()
|
||||||
..gridId = gridId
|
..gridId = gridId
|
||||||
..startRowId = rowId;
|
..startRowId = rowId;
|
||||||
|
|
||||||
return GridEventCreateRow(payload).send();
|
return GridEventCreateTableRow(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> moveRow({
|
Future<Either<Unit, FlowyError>> moveRow({
|
||||||
|
@ -3,7 +3,7 @@ import 'package:provider/provider.dart';
|
|||||||
import 'board_column/board_column.dart';
|
import 'board_column/board_column.dart';
|
||||||
import 'board_column/board_column_data.dart';
|
import 'board_column/board_column_data.dart';
|
||||||
import 'board_data.dart';
|
import 'board_data.dart';
|
||||||
import 'reorder_flex/drag_target_inteceptor.dart';
|
import 'reorder_flex/drag_target_interceptor.dart';
|
||||||
import 'reorder_flex/reorder_flex.dart';
|
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';
|
||||||
@ -143,7 +143,7 @@ class _BoardContentState extends State<BoardContent> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
_overlayEntry = BoardOverlayEntry(
|
_overlayEntry = BoardOverlayEntry(
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
final interceptor = OverlappingDragTargetInteceptor(
|
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,
|
||||||
|
@ -5,7 +5,7 @@ import '../../rendering/board_overlay.dart';
|
|||||||
import '../../utils/log.dart';
|
import '../../utils/log.dart';
|
||||||
import '../reorder_phantom/phantom_controller.dart';
|
import '../reorder_phantom/phantom_controller.dart';
|
||||||
import '../reorder_flex/reorder_flex.dart';
|
import '../reorder_flex/reorder_flex.dart';
|
||||||
import '../reorder_flex/drag_target_inteceptor.dart';
|
import '../reorder_flex/drag_target_interceptor.dart';
|
||||||
import 'board_column_data.dart';
|
import 'board_column_data.dart';
|
||||||
|
|
||||||
typedef OnColumnDragStarted = void Function(int index);
|
typedef OnColumnDragStarted = void Function(int index);
|
||||||
@ -37,7 +37,7 @@ typedef AFBoardColumnFooterBuilder = Widget Function(
|
|||||||
AFBoardColumnData columnData,
|
AFBoardColumnData columnData,
|
||||||
);
|
);
|
||||||
|
|
||||||
abstract class AFBoardColumnDataDataSource extends ReoderFlextDataSource {
|
abstract class AFBoardColumnDataDataSource extends ReoderFlexDataSource {
|
||||||
AFBoardColumnData get columnData;
|
AFBoardColumnData get columnData;
|
||||||
|
|
||||||
List<String> get acceptedColumnIds;
|
List<String> get acceptedColumnIds;
|
||||||
|
@ -24,7 +24,7 @@ typedef OnMoveColumnItemToColumn = void Function(
|
|||||||
);
|
);
|
||||||
|
|
||||||
class AFBoardDataController extends ChangeNotifier
|
class AFBoardDataController extends ChangeNotifier
|
||||||
with EquatableMixin, BoardPhantomControllerDelegate, ReoderFlextDataSource {
|
with EquatableMixin, BoardPhantomControllerDelegate, ReoderFlexDataSource {
|
||||||
final List<AFBoardColumnData> _columnDatas = [];
|
final List<AFBoardColumnData> _columnDatas = [];
|
||||||
final OnMoveColumn? onMoveColumn;
|
final OnMoveColumn? onMoveColumn;
|
||||||
final OnMoveColumnItem? onMoveColumnItem;
|
final OnMoveColumnItem? onMoveColumnItem;
|
||||||
|
@ -13,14 +13,14 @@ abstract class ReorderFlexDraggableTargetBuilder {
|
|||||||
Widget child,
|
Widget child,
|
||||||
DragTargetOnStarted onDragStarted,
|
DragTargetOnStarted onDragStarted,
|
||||||
DragTargetOnEnded<T> onDragEnded,
|
DragTargetOnEnded<T> onDragEnded,
|
||||||
DragTargetWillAccpet<T> onWillAccept,
|
DragTargetWillAccepted<T> onWillAccept,
|
||||||
AnimationController insertAnimationController,
|
AnimationController insertAnimationController,
|
||||||
AnimationController deleteAnimationController,
|
AnimationController deleteAnimationController,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
typedef DragTargetWillAccpet<T extends DragTargetData> = bool Function(
|
typedef DragTargetWillAccepted<T extends DragTargetData> = bool Function(
|
||||||
T dragTargetData);
|
T dragTargetData);
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -51,7 +51,7 @@ class ReorderDragTarget<T extends DragTargetData> extends StatefulWidget {
|
|||||||
///
|
///
|
||||||
/// [toAccept] represents the dragTarget index, which is the value passed in
|
/// [toAccept] represents the dragTarget index, which is the value passed in
|
||||||
/// when creating the [ReorderDragTarget].
|
/// when creating the [ReorderDragTarget].
|
||||||
final DragTargetWillAccpet<T> onWillAccept;
|
final DragTargetWillAccepted<T> onWillAccept;
|
||||||
|
|
||||||
/// Called when an acceptable piece of data was dropped over this drag target.
|
/// Called when an acceptable piece of data was dropped over this drag target.
|
||||||
///
|
///
|
||||||
@ -228,7 +228,7 @@ class DragTargetAnimation {
|
|||||||
value: 0.0, vsync: vsync, duration: const Duration(milliseconds: 10));
|
value: 0.0, vsync: vsync, duration: const Duration(milliseconds: 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
void startDargging() {
|
void startDragging() {
|
||||||
entranceController.value = 1.0;
|
entranceController.value = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,7 +386,7 @@ class FakeDragTarget<T extends DragTargetData> extends StatefulWidget {
|
|||||||
final FakeDragTargetEventData eventData;
|
final FakeDragTargetEventData eventData;
|
||||||
final DragTargetOnStarted onDragStarted;
|
final DragTargetOnStarted onDragStarted;
|
||||||
final DragTargetOnEnded<T> onDragEnded;
|
final DragTargetOnEnded<T> onDragEnded;
|
||||||
final DragTargetWillAccpet<T> onWillAccept;
|
final DragTargetWillAccepted<T> onWillAccept;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
final AnimationController insertAnimationController;
|
final AnimationController insertAnimationController;
|
||||||
final AnimationController deleteAnimationController;
|
final AnimationController deleteAnimationController;
|
||||||
|
@ -40,18 +40,18 @@ abstract class OverlapDragTargetDelegate {
|
|||||||
bool canMoveTo(String dragTargetId);
|
bool canMoveTo(String dragTargetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [OverlappingDragTargetInteceptor] is used to receive the overlapping
|
/// [OverlappingDragTargetInterceptor] is used to receive the overlapping
|
||||||
/// [DragTarget] event. If a [DragTarget] child is [DragTarget], it will
|
/// [DragTarget] event. If a [DragTarget] child is [DragTarget], it will
|
||||||
/// receive the [DragTarget] event when being dragged.
|
/// receive the [DragTarget] event when being dragged.
|
||||||
///
|
///
|
||||||
/// Receive the [DragTarget] event if the [acceptedReorderFlexId] contains
|
/// Receive the [DragTarget] event if the [acceptedReorderFlexId] contains
|
||||||
/// the passed in dragTarget' reorderFlexId.
|
/// the passed in dragTarget' reorderFlexId.
|
||||||
class OverlappingDragTargetInteceptor extends DragTargetInterceptor {
|
class OverlappingDragTargetInterceptor extends DragTargetInterceptor {
|
||||||
final String reorderFlexId;
|
final String reorderFlexId;
|
||||||
final List<String> acceptedReorderFlexId;
|
final List<String> acceptedReorderFlexId;
|
||||||
final OverlapDragTargetDelegate delegate;
|
final OverlapDragTargetDelegate delegate;
|
||||||
|
|
||||||
OverlappingDragTargetInteceptor({
|
OverlappingDragTargetInterceptor({
|
||||||
required this.delegate,
|
required this.delegate,
|
||||||
required this.reorderFlexId,
|
required this.reorderFlexId,
|
||||||
required this.acceptedReorderFlexId,
|
required this.acceptedReorderFlexId,
|
@ -7,25 +7,25 @@ import '../../utils/log.dart';
|
|||||||
import 'reorder_mixin.dart';
|
import 'reorder_mixin.dart';
|
||||||
import 'drag_target.dart';
|
import 'drag_target.dart';
|
||||||
import 'drag_state.dart';
|
import 'drag_state.dart';
|
||||||
import 'drag_target_inteceptor.dart';
|
import 'drag_target_interceptor.dart';
|
||||||
|
|
||||||
typedef OnDragStarted = void Function(int index);
|
typedef OnDragStarted = void Function(int index);
|
||||||
typedef OnDragEnded = void Function();
|
typedef OnDragEnded = void Function();
|
||||||
typedef OnReorder = void Function(int fromIndex, int toIndex);
|
typedef OnReorder = void Function(int fromIndex, int toIndex);
|
||||||
typedef OnDeleted = void Function(int deletedIndex);
|
typedef OnDeleted = void Function(int deletedIndex);
|
||||||
typedef OnInserted = void Function(int insertedIndex);
|
typedef OnInserted = void Function(int insertedIndex);
|
||||||
typedef OnReveivePassedInPhantom = void Function(
|
typedef OnReceivePassedInPhantom = void Function(
|
||||||
FlexDragTargetData dragTargetData, int phantomIndex);
|
FlexDragTargetData dragTargetData, int phantomIndex);
|
||||||
|
|
||||||
abstract class ReoderFlextDataSource {
|
abstract class ReoderFlexDataSource {
|
||||||
/// [identifier] represents the id the [ReorderFlex]. It must be unique.
|
/// [identifier] represents the id the [ReorderFlex]. It must be unique.
|
||||||
String get identifier;
|
String get identifier;
|
||||||
|
|
||||||
/// The number of [ReoderFlexItem]s will be displaied in the [ReorderFlex].
|
/// The number of [ReoderFlexItem]s will be displayed in the [ReorderFlex].
|
||||||
UnmodifiableListView<ReoderFlexItem> get items;
|
UnmodifiableListView<ReoderFlexItem> get items;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Each item displaied in the [ReorderFlex] required to implement the [ReoderFlexItem].
|
/// Each item displayed in the [ReorderFlex] required to implement the [ReoderFlexItem].
|
||||||
abstract class ReoderFlexItem {
|
abstract class ReoderFlexItem {
|
||||||
/// [id] is used to identify the item. It must be unique.
|
/// [id] is used to identify the item. It must be unique.
|
||||||
String get id;
|
String get id;
|
||||||
@ -70,7 +70,7 @@ class ReorderFlex extends StatefulWidget {
|
|||||||
/// [onDragEnded] is called when dragTarget did end dragging
|
/// [onDragEnded] is called when dragTarget did end dragging
|
||||||
final OnDragEnded? onDragEnded;
|
final OnDragEnded? onDragEnded;
|
||||||
|
|
||||||
final ReoderFlextDataSource dataSource;
|
final ReoderFlexDataSource dataSource;
|
||||||
|
|
||||||
final DragTargetInterceptor? interceptor;
|
final DragTargetInterceptor? interceptor;
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ class ReorderFlexState extends State<ReorderFlex>
|
|||||||
void _requestAnimationToNextIndex({bool isAcceptingNewTarget = false}) {
|
void _requestAnimationToNextIndex({bool isAcceptingNewTarget = false}) {
|
||||||
/// Update the dragState and animate to the next index if the current
|
/// Update the dragState and animate to the next index if the current
|
||||||
/// dragging animation is completed. Otherwise, it will get called again
|
/// dragging animation is completed. Otherwise, it will get called again
|
||||||
/// when the animation finishs.
|
/// when the animation finish.
|
||||||
|
|
||||||
if (_animation.entranceController.isCompleted) {
|
if (_animation.entranceController.isCompleted) {
|
||||||
dragState.removePhantom();
|
dragState.removePhantom();
|
||||||
@ -425,7 +425,7 @@ class ReorderFlexState extends State<ReorderFlex>
|
|||||||
) {
|
) {
|
||||||
setState(() {
|
setState(() {
|
||||||
dragState.startDragging(draggingWidget, dragIndex, feedbackSize);
|
dragState.startDragging(draggingWidget, dragIndex, feedbackSize);
|
||||||
_animation.startDargging();
|
_animation.startDragging();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
import '../../utils/log.dart';
|
import '../../utils/log.dart';
|
||||||
import '../board_column/board_column_data.dart';
|
import '../board_column/board_column_data.dart';
|
||||||
import '../reorder_flex/drag_state.dart';
|
import '../reorder_flex/drag_state.dart';
|
||||||
import '../reorder_flex/drag_target.dart';
|
import '../reorder_flex/drag_target.dart';
|
||||||
import '../reorder_flex/drag_target_inteceptor.dart';
|
import '../reorder_flex/drag_target_interceptor.dart';
|
||||||
import 'phantom_state.dart';
|
import 'phantom_state.dart';
|
||||||
|
|
||||||
abstract class BoardPhantomControllerDelegate {
|
abstract class BoardPhantomControllerDelegate {
|
||||||
@ -61,7 +62,7 @@ class BoardPhantomController extends OverlapDragTargetDelegate
|
|||||||
columnsState.setColumnIsDragging(columnId, false);
|
columnsState.setColumnIsDragging(columnId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove the phanton in the column when the column is end dragging.
|
/// Remove the phantom in the column when the column is end dragging.
|
||||||
void columnEndDragging(String columnId) {
|
void columnEndDragging(String columnId) {
|
||||||
columnsState.setColumnIsDragging(columnId, true);
|
columnsState.setColumnIsDragging(columnId, true);
|
||||||
if (phantomRecord == null) return;
|
if (phantomRecord == null) return;
|
||||||
@ -331,7 +332,7 @@ class PhantomDraggableBuilder extends ReorderFlexDraggableTargetBuilder {
|
|||||||
Widget child,
|
Widget child,
|
||||||
DragTargetOnStarted onDragStarted,
|
DragTargetOnStarted onDragStarted,
|
||||||
DragTargetOnEnded<T> onDragEnded,
|
DragTargetOnEnded<T> onDragEnded,
|
||||||
DragTargetWillAccpet<T> onWillAccept,
|
DragTargetWillAccepted<T> onWillAccept,
|
||||||
AnimationController insertAnimationController,
|
AnimationController insertAnimationController,
|
||||||
AnimationController deleteAnimationController,
|
AnimationController deleteAnimationController,
|
||||||
) {
|
) {
|
||||||
|
@ -11,7 +11,7 @@ pub enum GridNotification {
|
|||||||
DidUpdateRow = 30,
|
DidUpdateRow = 30,
|
||||||
DidUpdateCell = 40,
|
DidUpdateCell = 40,
|
||||||
DidUpdateField = 50,
|
DidUpdateField = 50,
|
||||||
DidUpdateBoard = 60,
|
DidUpdateGroup = 60,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::default::Default for GridNotification {
|
impl std::default::Default for GridNotification {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::entities::{CreateRowParams, GridLayout, RowPB};
|
use crate::entities::{CreateRowParams, GridLayout};
|
||||||
use flowy_derive::ProtoBuf;
|
use flowy_derive::ProtoBuf;
|
||||||
use flowy_error::ErrorCode;
|
use flowy_error::ErrorCode;
|
||||||
use flowy_grid_data_model::parser::NotEmptyStr;
|
use flowy_grid_data_model::parser::NotEmptyStr;
|
||||||
@ -26,43 +26,3 @@ impl TryInto<CreateRowParams> for CreateBoardCardPayloadPB {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, ProtoBuf)]
|
|
||||||
pub struct GroupRowsChangesetPB {
|
|
||||||
#[pb(index = 1)]
|
|
||||||
pub group_id: String,
|
|
||||||
|
|
||||||
#[pb(index = 2)]
|
|
||||||
pub inserted_rows: Vec<RowPB>,
|
|
||||||
|
|
||||||
#[pb(index = 3)]
|
|
||||||
pub deleted_rows: Vec<String>,
|
|
||||||
|
|
||||||
#[pb(index = 4)]
|
|
||||||
pub updated_rows: Vec<RowPB>,
|
|
||||||
}
|
|
||||||
impl GroupRowsChangesetPB {
|
|
||||||
pub fn insert(group_id: String, inserted_rows: Vec<RowPB>) -> Self {
|
|
||||||
Self {
|
|
||||||
group_id,
|
|
||||||
inserted_rows,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn delete(group_id: String, deleted_rows: Vec<String>) -> Self {
|
|
||||||
Self {
|
|
||||||
group_id,
|
|
||||||
deleted_rows,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update(group_id: String, updated_rows: Vec<RowPB>) -> Self {
|
|
||||||
Self {
|
|
||||||
group_id,
|
|
||||||
updated_rows,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
use crate::entities::{InsertedRowPB, RowPB};
|
||||||
|
use flowy_derive::ProtoBuf;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, ProtoBuf)]
|
||||||
|
pub struct GroupRowsChangesetPB {
|
||||||
|
#[pb(index = 1)]
|
||||||
|
pub group_id: String,
|
||||||
|
|
||||||
|
#[pb(index = 2)]
|
||||||
|
pub inserted_rows: Vec<InsertedRowPB>,
|
||||||
|
|
||||||
|
#[pb(index = 3)]
|
||||||
|
pub deleted_rows: Vec<String>,
|
||||||
|
|
||||||
|
#[pb(index = 4)]
|
||||||
|
pub updated_rows: Vec<RowPB>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GroupRowsChangesetPB {
|
||||||
|
pub fn insert(group_id: String, inserted_rows: Vec<InsertedRowPB>) -> Self {
|
||||||
|
Self {
|
||||||
|
group_id,
|
||||||
|
inserted_rows,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete(group_id: String, deleted_rows: Vec<String>) -> Self {
|
||||||
|
Self {
|
||||||
|
group_id,
|
||||||
|
deleted_rows,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(group_id: String, updated_rows: Vec<RowPB>) -> Self {
|
||||||
|
Self {
|
||||||
|
group_id,
|
||||||
|
updated_rows,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
mod board_card;
|
mod board_card;
|
||||||
mod configuration;
|
mod configuration;
|
||||||
mod group;
|
mod group;
|
||||||
|
mod group_changeset;
|
||||||
|
|
||||||
pub use board_card::*;
|
pub use board_card::*;
|
||||||
pub use configuration::*;
|
pub use configuration::*;
|
||||||
pub use group::*;
|
pub use group::*;
|
||||||
|
pub use group_changeset::*;
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
use flowy_error::{FlowyError, FlowyResult};
|
use flowy_error::{FlowyError, FlowyResult};
|
||||||
|
|
||||||
use crate::entities::{
|
use crate::entities::{
|
||||||
CreateRowParams, GridFilterConfiguration, GridLayout, GridSettingPB, GroupPB, GroupRowsChangesetPB, RowPB,
|
CreateRowParams, GridFilterConfiguration, GridLayout, GridSettingPB, GroupPB, GroupRowsChangesetPB, InsertedRowPB,
|
||||||
|
RowPB,
|
||||||
};
|
};
|
||||||
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
||||||
use crate::services::group::{default_group_configuration, Group, GroupConfigurationDelegate, GroupService};
|
use crate::services::group::{default_group_configuration, Group, GroupConfigurationDelegate, GroupService};
|
||||||
@ -91,8 +92,6 @@ impl GridViewRevisionEditor {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
|
pub(crate) async fn did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
|
||||||
@ -100,7 +99,11 @@ impl GridViewRevisionEditor {
|
|||||||
match params.group_id.as_ref() {
|
match params.group_id.as_ref() {
|
||||||
None => {}
|
None => {}
|
||||||
Some(group_id) => {
|
Some(group_id) => {
|
||||||
let changeset = GroupRowsChangesetPB::insert(group_id.clone(), vec![row_pb.clone()]);
|
let inserted_row = InsertedRowPB {
|
||||||
|
row: row_pb.clone(),
|
||||||
|
index: None,
|
||||||
|
};
|
||||||
|
let changeset = GroupRowsChangesetPB::insert(group_id.clone(), vec![inserted_row]);
|
||||||
self.notify_did_update_group(changeset).await;
|
self.notify_did_update_group(changeset).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,7 +123,7 @@ impl GridViewRevisionEditor {
|
|||||||
async fn group_id_of_row(&self, row_id: &str) -> Option<String> {
|
async fn group_id_of_row(&self, row_id: &str) -> Option<String> {
|
||||||
let read_guard = self.groups.read().await;
|
let read_guard = self.groups.read().await;
|
||||||
for group in read_guard.iter() {
|
for group in read_guard.iter() {
|
||||||
if group.rows.iter().find(|row| row.id == row_id).is_some() {
|
if group.rows.iter().any(|row| row.id == row_id) {
|
||||||
return Some(group.id.clone());
|
return Some(group.id.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,7 +170,7 @@ impl GridViewRevisionEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn notify_did_update_group(&self, changeset: GroupRowsChangesetPB) {
|
async fn notify_did_update_group(&self, changeset: GroupRowsChangesetPB) {
|
||||||
send_dart_notification(&changeset.group_id, GridNotification::DidUpdateBoard)
|
send_dart_notification(&changeset.group_id, GridNotification::DidUpdateGroup)
|
||||||
.payload(changeset)
|
.payload(changeset)
|
||||||
.send();
|
.send();
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
use crate::dart_notification::{send_dart_notification, GridNotification};
|
|
||||||
use crate::entities::{
|
use crate::entities::{
|
||||||
CheckboxGroupConfigurationPB, DateGroupConfigurationPB, FieldType, GroupPB, GroupRowsChangesetPB,
|
CheckboxGroupConfigurationPB, DateGroupConfigurationPB, FieldType, NumberGroupConfigurationPB,
|
||||||
NumberGroupConfigurationPB, RowPB, SelectOptionGroupConfigurationPB, TextGroupConfigurationPB,
|
SelectOptionGroupConfigurationPB, TextGroupConfigurationPB, UrlGroupConfigurationPB,
|
||||||
UrlGroupConfigurationPB,
|
|
||||||
};
|
};
|
||||||
use crate::services::group::{
|
use crate::services::group::{
|
||||||
CheckboxGroupController, Group, GroupActionHandler, MultiSelectGroupController, SingleSelectGroupController,
|
CheckboxGroupController, Group, GroupActionHandler, MultiSelectGroupController, SingleSelectGroupController,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user