chore: create board card

This commit is contained in:
appflowy 2022-08-16 17:13:56 +08:00
parent b7d71428be
commit bc346dfd67
20 changed files with 240 additions and 98 deletions

View File

@ -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) {}
}

View File

@ -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),
), ),

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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),

View File

@ -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) {

View File

@ -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({

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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();
}); });
} }

View File

@ -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,
) { ) {

View File

@ -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 {

View File

@ -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()
}
}
}

View File

@ -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()
}
}
}

View File

@ -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::*;

View File

@ -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();
} }

View File

@ -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,