Browse Source

refactor: remove UpdateRowPB, refactor RowInfo class

appflowy 2 years ago
parent
commit
57ede798d8
19 changed files with 118 additions and 159 deletions
  1. 9 3
      frontend/app_flowy/lib/plugins/board/application/board_bloc.dart
  2. 16 29
      frontend/app_flowy/lib/plugins/board/application/board_data_controller.dart
  3. 2 2
      frontend/app_flowy/lib/plugins/board/application/card/card_bloc.dart
  4. 1 1
      frontend/app_flowy/lib/plugins/board/application/card/card_data_controller.dart
  5. 1 1
      frontend/app_flowy/lib/plugins/board/board.dart
  6. 2 2
      frontend/app_flowy/lib/plugins/grid/application/block/block_cache.dart
  7. 2 2
      frontend/app_flowy/lib/plugins/grid/application/grid_bloc.dart
  8. 2 2
      frontend/app_flowy/lib/plugins/grid/application/grid_data_controller.dart
  9. 5 5
      frontend/app_flowy/lib/plugins/grid/application/row/row_action_sheet_bloc.dart
  10. 3 3
      frontend/app_flowy/lib/plugins/grid/application/row/row_bloc.dart
  11. 47 45
      frontend/app_flowy/lib/plugins/grid/application/row/row_cache.dart
  12. 3 3
      frontend/app_flowy/lib/plugins/grid/application/row/row_data_controller.dart
  13. 2 2
      frontend/app_flowy/lib/plugins/grid/presentation/grid_page.dart
  14. 1 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/grid_row.dart
  15. 1 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_action_sheet.dart
  16. 6 39
      frontend/rust-lib/flowy-grid/src/entities/block_entities.rs
  17. 1 1
      frontend/rust-lib/flowy-grid/src/event_handler.rs
  18. 12 15
      frontend/rust-lib/flowy-grid/src/services/block_manager.rs
  19. 2 2
      frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs

+ 9 - 3
frontend/app_flowy/lib/plugins/board/application/board_bloc.dart

@@ -52,8 +52,12 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
             _startListening();
             await _loadGrid(emit);
           },
-          createRow: () {
-            _dataController.createRow();
+          createRow: () async {
+            final result = await _dataController.createRow();
+            result.fold(
+              (rowPB) => null,
+              (err) => Log.error(err),
+            );
           },
           didReceiveGridUpdate: (GridPB grid) {
             emit(state.copyWith(grid: Some(grid)));
@@ -99,7 +103,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
 
         boardDataController.addColumns(columns);
       },
-      onRowsChanged: (List<RowInfo> rowInfos, RowChangeReason reason) {
+      onRowsChanged: (List<RowInfo> rowInfos, RowsChangedReason reason) {
         add(BoardEvent.didReceiveRows(rowInfos));
       },
       onError: (err) {
@@ -156,6 +160,7 @@ class BoardState with _$BoardState {
     required String gridId,
     required Option<GridPB> grid,
     required List<GroupPB> groups,
+    required Option<RowPB> editingRow,
     required List<RowInfo> rowInfos,
     required GridLoadingState loadingState,
   }) = _BoardState;
@@ -165,6 +170,7 @@ class BoardState with _$BoardState {
         groups: [],
         grid: none(),
         gridId: gridId,
+        editingRow: none(),
         loadingState: const _Loading(),
       );
 }

+ 16 - 29
frontend/app_flowy/lib/plugins/board/application/board_data_controller.dart

@@ -4,7 +4,6 @@ import 'package:app_flowy/plugins/grid/application/block/block_cache.dart';
 import 'package:app_flowy/plugins/grid/application/field/field_cache.dart';
 import 'package:app_flowy/plugins/grid/application/grid_service.dart';
 import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
-import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
 import 'dart:async';
@@ -15,8 +14,8 @@ typedef OnFieldsChanged = void Function(UnmodifiableListView<FieldPB>);
 typedef OnGridChanged = void Function(GridPB);
 typedef OnGroupChanged = void Function(List<GroupPB>);
 typedef OnRowsChanged = void Function(
-  List<RowInfo> rowInfos,
-  RowChangeReason,
+  List<RowInfo>,
+  RowsChangedReason,
 );
 typedef OnError = void Function(FlowyError);
 
@@ -73,11 +72,11 @@ class BoardDataController {
       () => result.fold(
         (grid) async {
           _onGridChanged?.call(grid);
-          _initialBlocks(grid.blocks);
+
           return await _loadFields(grid).then((result) {
             return result.fold(
               (l) {
-                _loadGroups();
+                _loadGroups(grid.blocks);
                 return left(l);
               },
               (err) => right(err),
@@ -102,29 +101,6 @@ class BoardDataController {
     }
   }
 
-  void _initialBlocks(List<BlockPB> blocks) {
-    for (final block in blocks) {
-      if (_blocks[block.id] != null) {
-        Log.warn("Initial duplicate block's cache: ${block.id}");
-        return;
-      }
-
-      final cache = GridBlockCache(
-        gridId: gridId,
-        block: block,
-        fieldCache: fieldCache,
-      );
-
-      cache.addListener(
-        onChangeReason: (reason) {
-          _onRowsChanged?.call(rowInfos, reason);
-        },
-      );
-
-      _blocks[block.id] = cache;
-    }
-  }
-
   Future<Either<Unit, FlowyError>> _loadFields(GridPB grid) async {
     final result = await _gridFFIService.getFields(fieldIds: grid.fields);
     return Future(
@@ -139,7 +115,18 @@ class BoardDataController {
     );
   }
 
-  Future<void> _loadGroups() async {
+  Future<void> _loadGroups(List<BlockPB> blocks) async {
+    for (final block in blocks) {
+      final cache = GridBlockCache(
+        gridId: gridId,
+        block: block,
+        fieldCache: fieldCache,
+      );
+
+      // cache.addListener(onRowsChanged: (rows, reason) {})
+      _blocks[block.id] = cache;
+    }
+
     final result = await _gridFFIService.loadGroups();
     return Future(
       () => result.fold(

+ 2 - 2
frontend/app_flowy/lib/plugins/board/application/card/card_bloc.dart

@@ -74,7 +74,7 @@ class BoardCardEvent with _$BoardCardEvent {
   const factory BoardCardEvent.initial() = _InitialRow;
   const factory BoardCardEvent.createRow() = _CreateRow;
   const factory BoardCardEvent.didReceiveCells(
-      GridCellMap gridCellMap, RowChangeReason reason) = _DidReceiveCells;
+      GridCellMap gridCellMap, RowsChangedReason reason) = _DidReceiveCells;
 }
 
 @freezed
@@ -83,7 +83,7 @@ class BoardCardState with _$BoardCardState {
     required RowPB rowPB,
     required GridCellMap gridCellMap,
     required UnmodifiableListView<GridCellEquatable> cells,
-    RowChangeReason? changeReason,
+    RowsChangedReason? changeReason,
   }) = _BoardCardState;
 
   factory BoardCardState.initial(RowPB rowPB, GridCellMap cellDataMap) =>

+ 1 - 1
frontend/app_flowy/lib/plugins/board/application/card/card_data_controller.dart

@@ -6,7 +6,7 @@ import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
 import 'package:flutter/foundation.dart';
 
-typedef OnCardChanged = void Function(GridCellMap, RowChangeReason);
+typedef OnCardChanged = void Function(GridCellMap, RowsChangedReason);
 
 class CardDataController extends BoardCellBuilderDelegate {
   final RowPB rowPB;

+ 1 - 1
frontend/app_flowy/lib/plugins/board/board.dart

@@ -31,7 +31,7 @@ class BoardPluginBuilder implements PluginBuilder {
 
 class BoardPluginConfig implements PluginConfig {
   @override
-  bool get creatable => false;
+  bool get creatable => true;
 }
 
 class BoardPlugin extends Plugin {

+ 2 - 2
frontend/app_flowy/lib/plugins/grid/application/block/block_cache.dart

@@ -42,7 +42,7 @@ class GridBlockCache {
   }
 
   void addListener({
-    required void Function(RowChangeReason) onChangeReason,
+    required void Function(RowsChangedReason) onRowsChanged,
     bool Function()? listenWhen,
   }) {
     _rowCache.onRowsChanged((reason) {
@@ -50,7 +50,7 @@ class GridBlockCache {
         return;
       }
 
-      onChangeReason(reason);
+      onRowsChanged(reason);
     });
   }
 }

+ 2 - 2
frontend/app_flowy/lib/plugins/grid/application/grid_bloc.dart

@@ -98,7 +98,7 @@ class GridEvent with _$GridEvent {
   const factory GridEvent.createRow() = _CreateRow;
   const factory GridEvent.didReceiveRowUpdate(
     List<RowInfo> rows,
-    RowChangeReason listState,
+    RowsChangedReason listState,
   ) = _DidReceiveRowUpdate;
   const factory GridEvent.didReceiveFieldUpdate(
     UnmodifiableListView<FieldPB> fields,
@@ -117,7 +117,7 @@ class GridState with _$GridState {
     required GridFieldEquatable fields,
     required List<RowInfo> rowInfos,
     required GridLoadingState loadingState,
-    required RowChangeReason reason,
+    required RowsChangedReason reason,
   }) = _GridState;
 
   factory GridState.initial(String gridId) => GridState(

+ 2 - 2
frontend/app_flowy/lib/plugins/grid/application/grid_data_controller.dart

@@ -18,7 +18,7 @@ typedef OnGridChanged = void Function(GridPB);
 
 typedef OnRowsChanged = void Function(
   List<RowInfo> rowInfos,
-  RowChangeReason,
+  RowsChangedReason,
 );
 typedef ListenOnRowChangedCondition = bool Function();
 
@@ -105,7 +105,7 @@ class GridDataController {
       );
 
       cache.addListener(
-        onChangeReason: (reason) {
+        onRowsChanged: (reason) {
           _onRowChanged?.call(rowInfos, reason);
         },
       );

+ 5 - 5
frontend/app_flowy/lib/plugins/grid/application/row/row_action_sheet_bloc.dart

@@ -14,13 +14,13 @@ class RowActionSheetBloc
     extends Bloc<RowActionSheetEvent, RowActionSheetState> {
   final RowFFIService _rowService;
 
-  RowActionSheetBloc({required RowInfo rowData})
+  RowActionSheetBloc({required RowInfo rowInfo})
       : _rowService = RowFFIService(
-          gridId: rowData.gridId,
-          blockId: rowData.blockId,
-          rowId: rowData.id,
+          gridId: rowInfo.gridId,
+          blockId: rowInfo.blockId,
+          rowId: rowInfo.rowPB.id,
         ),
-        super(RowActionSheetState.initial(rowData)) {
+        super(RowActionSheetState.initial(rowInfo)) {
     on<RowActionSheetEvent>(
       (event, emit) async {
         await event.map(

+ 3 - 3
frontend/app_flowy/lib/plugins/grid/application/row/row_bloc.dart

@@ -21,7 +21,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
   })  : _rowService = RowFFIService(
           gridId: rowInfo.gridId,
           blockId: rowInfo.blockId,
-          rowId: rowInfo.id,
+          rowId: rowInfo.rowPB.id,
         ),
         _dataController = dataController,
         super(RowState.initial(rowInfo, dataController.loadData())) {
@@ -71,7 +71,7 @@ class RowEvent with _$RowEvent {
   const factory RowEvent.initial() = _InitialRow;
   const factory RowEvent.createRow() = _CreateRow;
   const factory RowEvent.didReceiveCells(
-      GridCellMap gridCellMap, RowChangeReason reason) = _DidReceiveCells;
+      GridCellMap gridCellMap, RowsChangedReason reason) = _DidReceiveCells;
 }
 
 @freezed
@@ -80,7 +80,7 @@ class RowState with _$RowState {
     required RowInfo rowInfo,
     required GridCellMap gridCellMap,
     required UnmodifiableListView<GridCellEquatable> cells,
-    RowChangeReason? changeReason,
+    RowsChangedReason? changeReason,
   }) = _RowState;
 
   factory RowState.initial(RowInfo rowInfo, GridCellMap cellDataMap) =>

+ 47 - 45
frontend/app_flowy/lib/plugins/grid/application/row/row_cache.dart

@@ -51,11 +51,9 @@ class GridRowCache {
         _fieldNotifier = notifier {
     //
     notifier.onRowFieldsChanged(() => _rowChangeReasonNotifier
-        .receive(const RowChangeReason.fieldDidChange()));
+        .receive(const RowsChangedReason.fieldDidChange()));
     notifier.onRowFieldChanged((field) => _cellCache.remove(field.id));
-    _rowInfos = block.rows
-        .map((rowInfo) => buildGridRow(rowInfo.id, rowInfo.height.toDouble()))
-        .toList();
+    _rowInfos = block.rows.map((rowPB) => buildGridRow(rowPB)).toList();
   }
 
   Future<void> dispose() async {
@@ -85,16 +83,16 @@ class GridRowCache {
       for (var rowId in deletedRows) rowId: rowId
     };
 
-    _rowInfos.asMap().forEach((index, row) {
-      if (deletedRowByRowId[row.id] == null) {
-        newRows.add(row);
+    _rowInfos.asMap().forEach((index, RowInfo rowInfo) {
+      if (deletedRowByRowId[rowInfo.rowPB.id] == null) {
+        newRows.add(rowInfo);
       } else {
-        _rowByRowId.remove(row.id);
-        deletedIndex.add(DeletedIndex(index: index, row: row));
+        _rowByRowId.remove(rowInfo.rowPB.id);
+        deletedIndex.add(DeletedIndex(index: index, row: rowInfo));
       }
     });
     _rowInfos = newRows;
-    _rowChangeReasonNotifier.receive(RowChangeReason.delete(deletedIndex));
+    _rowChangeReasonNotifier.receive(RowsChangedReason.delete(deletedIndex));
   }
 
   void _insertRows(List<InsertedRowPB> insertRows) {
@@ -103,39 +101,42 @@ class GridRowCache {
     }
 
     InsertedIndexs insertIndexs = [];
-    for (final insertRow in insertRows) {
+    for (final InsertedRowPB insertRow in insertRows) {
       final insertIndex = InsertedIndex(
         index: insertRow.index,
-        rowId: insertRow.rowId,
+        rowId: insertRow.row.id,
       );
       insertIndexs.add(insertIndex);
-      _rowInfos.insert(insertRow.index,
-          (buildGridRow(insertRow.rowId, insertRow.height.toDouble())));
+      _rowInfos.insert(
+        insertRow.index,
+        (buildGridRow(insertRow.row)),
+      );
     }
 
-    _rowChangeReasonNotifier.receive(RowChangeReason.insert(insertIndexs));
+    _rowChangeReasonNotifier.receive(RowsChangedReason.insert(insertIndexs));
   }
 
-  void _updateRows(List<UpdatedRowPB> updatedRows) {
+  void _updateRows(List<RowPB> updatedRows) {
     if (updatedRows.isEmpty) {
       return;
     }
 
     final UpdatedIndexs updatedIndexs = UpdatedIndexs();
-    for (final updatedRow in updatedRows) {
-      final rowId = updatedRow.rowId;
-      final index = _rowInfos.indexWhere((row) => row.id == rowId);
+    for (final RowPB updatedRow in updatedRows) {
+      final rowId = updatedRow.id;
+      final index = _rowInfos.indexWhere(
+        (rowInfo) => rowInfo.rowPB.id == rowId,
+      );
       if (index != -1) {
-        _rowByRowId[rowId] = updatedRow.row;
+        _rowByRowId[rowId] = updatedRow;
 
         _rowInfos.removeAt(index);
-        _rowInfos.insert(
-            index, buildGridRow(rowId, updatedRow.row.height.toDouble()));
+        _rowInfos.insert(index, buildGridRow(updatedRow));
         updatedIndexs[rowId] = UpdatedIndex(index: index, rowId: rowId);
       }
     }
 
-    _rowChangeReasonNotifier.receive(RowChangeReason.update(updatedIndexs));
+    _rowChangeReasonNotifier.receive(RowsChangedReason.update(updatedIndexs));
   }
 
   void _hideRows(List<String> hideRows) {}
@@ -143,7 +144,7 @@ class GridRowCache {
   void _showRows(List<String> visibleRows) {}
 
   void onRowsChanged(
-    void Function(RowChangeReason) onRowChanged,
+    void Function(RowsChangedReason) onRowChanged,
   ) {
     _rowChangeReasonNotifier.addListener(() {
       onRowChanged(_rowChangeReasonNotifier.reason);
@@ -152,7 +153,7 @@ class GridRowCache {
 
   RowUpdateCallback addListener({
     required String rowId,
-    void Function(GridCellMap, RowChangeReason)? onCellUpdated,
+    void Function(GridCellMap, RowsChangedReason)? onCellUpdated,
     bool Function()? listenWhen,
   }) {
     listenerHandler() async {
@@ -230,40 +231,43 @@ class GridRowCache {
 
     _rowByRowId[updatedRow.id] = updatedRow;
     final index =
-        _rowInfos.indexWhere((gridRow) => gridRow.id == updatedRow.id);
+        _rowInfos.indexWhere((rowInfo) => rowInfo.rowPB.id == updatedRow.id);
     if (index != -1) {
       // update the corresponding row in _rows if they are not the same
-      if (_rowInfos[index].rawRow != updatedRow) {
-        final row = _rowInfos.removeAt(index).copyWith(rawRow: updatedRow);
-        _rowInfos.insert(index, row);
+      if (_rowInfos[index].rowPB != updatedRow) {
+        final rowInfo = _rowInfos.removeAt(index).copyWith(rowPB: updatedRow);
+        _rowInfos.insert(index, rowInfo);
 
         // Calculate the update index
         final UpdatedIndexs updatedIndexs = UpdatedIndexs();
-        updatedIndexs[row.id] = UpdatedIndex(index: index, rowId: row.id);
+        updatedIndexs[rowInfo.rowPB.id] = UpdatedIndex(
+          index: index,
+          rowId: rowInfo.rowPB.id,
+        );
 
         //
-        _rowChangeReasonNotifier.receive(RowChangeReason.update(updatedIndexs));
+        _rowChangeReasonNotifier
+            .receive(RowsChangedReason.update(updatedIndexs));
       }
     }
   }
 
-  RowInfo buildGridRow(String rowId, double rowHeight) {
+  RowInfo buildGridRow(RowPB rowPB) {
     return RowInfo(
       gridId: gridId,
       blockId: block.id,
       fields: _fieldNotifier.fields,
-      id: rowId,
-      height: rowHeight,
+      rowPB: rowPB,
     );
   }
 }
 
 class _RowChangesetNotifier extends ChangeNotifier {
-  RowChangeReason reason = const InitialListState();
+  RowsChangedReason reason = const InitialListState();
 
   _RowChangesetNotifier();
 
-  void receive(RowChangeReason newReason) {
+  void receive(RowsChangedReason newReason) {
     reason = newReason;
     reason.map(
       insert: (_) => notifyListeners(),
@@ -280,10 +284,8 @@ class RowInfo with _$RowInfo {
   const factory RowInfo({
     required String gridId,
     required String blockId,
-    required String id,
     required UnmodifiableListView<FieldPB> fields,
-    required double height,
-    RowPB? rawRow,
+    required RowPB rowPB,
   }) = _RowInfo;
 }
 
@@ -292,12 +294,12 @@ typedef DeletedIndexs = List<DeletedIndex>;
 typedef UpdatedIndexs = LinkedHashMap<String, UpdatedIndex>;
 
 @freezed
-class RowChangeReason with _$RowChangeReason {
-  const factory RowChangeReason.insert(InsertedIndexs items) = _Insert;
-  const factory RowChangeReason.delete(DeletedIndexs items) = _Delete;
-  const factory RowChangeReason.update(UpdatedIndexs indexs) = _Update;
-  const factory RowChangeReason.fieldDidChange() = _FieldDidChange;
-  const factory RowChangeReason.initial() = InitialListState;
+class RowsChangedReason with _$RowsChangedReason {
+  const factory RowsChangedReason.insert(InsertedIndexs items) = _Insert;
+  const factory RowsChangedReason.delete(DeletedIndexs items) = _Delete;
+  const factory RowsChangedReason.update(UpdatedIndexs indexs) = _Update;
+  const factory RowsChangedReason.fieldDidChange() = _FieldDidChange;
+  const factory RowsChangedReason.initial() = InitialListState;
 }
 
 class InsertedIndex {

+ 3 - 3
frontend/app_flowy/lib/plugins/grid/application/row/row_data_controller.dart

@@ -5,7 +5,7 @@ import '../cell/cell_service/cell_service.dart';
 import '../field/field_cache.dart';
 import 'row_cache.dart';
 
-typedef OnRowChanged = void Function(GridCellMap, RowChangeReason);
+typedef OnRowChanged = void Function(GridCellMap, RowsChangedReason);
 
 class GridRowDataController extends GridCellBuilderDelegate {
   final RowInfo rowInfo;
@@ -21,12 +21,12 @@ class GridRowDataController extends GridCellBuilderDelegate {
         _rowCache = rowCache;
 
   GridCellMap loadData() {
-    return _rowCache.loadGridCells(rowInfo.id);
+    return _rowCache.loadGridCells(rowInfo.rowPB.id);
   }
 
   void addListener({OnRowChanged? onRowChanged}) {
     _onRowChangedListeners.add(_rowCache.addListener(
-      rowId: rowInfo.id,
+      rowId: rowInfo.rowPB.id,
       onCellUpdated: onRowChanged,
     ));
   }

+ 2 - 2
frontend/app_flowy/lib/plugins/grid/presentation/grid_page.dart

@@ -240,7 +240,7 @@ class _GridRowsState extends State<_GridRows> {
     Animation<double> animation,
   ) {
     final rowCache =
-        context.read<GridBloc>().getRowCache(rowInfo.blockId, rowInfo.id);
+        context.read<GridBloc>().getRowCache(rowInfo.blockId, rowInfo.rowPB.id);
 
     /// Return placeholder widget if the rowCache is null.
     if (rowCache == null) return const SizedBox();
@@ -267,7 +267,7 @@ class _GridRowsState extends State<_GridRows> {
             cellBuilder,
           );
         },
-        key: ValueKey(rowInfo.id),
+        key: ValueKey(rowInfo.rowPB.id),
       ),
     );
   }

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/grid_row.dart

@@ -52,7 +52,7 @@ class _GridRowWidgetState extends State<GridRowWidget> {
       value: _rowBloc,
       child: _RowEnterRegion(
         child: BlocBuilder<RowBloc, RowState>(
-          buildWhen: (p, c) => p.rowInfo.height != c.rowInfo.height,
+          buildWhen: (p, c) => p.rowInfo.rowPB.height != c.rowInfo.rowPB.height,
           builder: (context, state) {
             final children = [
               const _RowLeading(),

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_action_sheet.dart

@@ -21,7 +21,7 @@ class GridRowActionSheet extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return BlocProvider(
-      create: (context) => RowActionSheetBloc(rowData: rowData),
+      create: (context) => RowActionSheetBloc(rowInfo: rowData),
       child: BlocBuilder<RowActionSheetBloc, RowActionSheetState>(
         builder: (context, state) {
           final cells = _RowAction.values

+ 6 - 39
frontend/rust-lib/flowy-grid/src/entities/block_entities.rs

@@ -106,48 +106,15 @@ impl std::convert::From<Vec<BlockPB>> for RepeatedBlockPB {
 #[derive(Debug, Clone, Default, ProtoBuf)]
 pub struct InsertedRowPB {
     #[pb(index = 1)]
-    pub block_id: String,
-
-    #[pb(index = 2)]
-    pub row_id: String,
-
-    #[pb(index = 3)]
-    pub height: i32,
-
-    #[pb(index = 4, one_of)]
-    pub index: Option<i32>,
-}
-
-#[derive(Debug, Default, ProtoBuf)]
-pub struct UpdatedRowPB {
-    #[pb(index = 1)]
-    pub block_id: String,
-
-    #[pb(index = 2)]
-    pub row_id: String,
-
-    #[pb(index = 3)]
     pub row: RowPB,
-}
 
-impl UpdatedRowPB {
-    pub fn new(row_rev: &RowRevision, row: RowPB) -> Self {
-        Self {
-            row_id: row_rev.id.clone(),
-            block_id: row_rev.block_id.clone(),
-            row,
-        }
-    }
+    #[pb(index = 2, one_of)]
+    pub index: Option<i32>,
 }
 
 impl std::convert::From<RowPB> for InsertedRowPB {
-    fn from(row_info: RowPB) -> Self {
-        Self {
-            row_id: row_info.id,
-            block_id: row_info.block_id,
-            height: row_info.height,
-            index: None,
-        }
+    fn from(row: RowPB) -> Self {
+        Self { row, index: None }
     }
 }
 
@@ -170,7 +137,7 @@ pub struct GridBlockChangesetPB {
     pub deleted_rows: Vec<String>,
 
     #[pb(index = 4)]
-    pub updated_rows: Vec<UpdatedRowPB>,
+    pub updated_rows: Vec<RowPB>,
 
     #[pb(index = 5)]
     pub visible_rows: Vec<String>,
@@ -195,7 +162,7 @@ impl GridBlockChangesetPB {
         }
     }
 
-    pub fn update(block_id: &str, updated_rows: Vec<UpdatedRowPB>) -> Self {
+    pub fn update(block_id: &str, updated_rows: Vec<RowPB>) -> Self {
         Self {
             block_id: block_id.to_owned(),
             updated_rows,

+ 1 - 1
frontend/rust-lib/flowy-grid/src/event_handler.rs

@@ -235,7 +235,7 @@ pub(crate) async fn get_row_handler(
     let row = editor
         .get_row_rev(&params.row_id)
         .await?
-        .and_then(make_row_from_row_rev);
+        .and_then(|row_rev| Some(make_row_from_row_rev(row_rev)));
 
     data_result(OptionalRowPB { row })
 }

+ 12 - 15
frontend/rust-lib/flowy-grid/src/services/block_manager.rs

@@ -1,9 +1,9 @@
 use crate::dart_notification::{send_dart_notification, GridNotification};
-use crate::entities::{CellChangesetPB, GridBlockChangesetPB, InsertedRowPB, RowPB, UpdatedRowPB};
+use crate::entities::{CellChangesetPB, GridBlockChangesetPB, InsertedRowPB, RowPB};
 use crate::manager::GridUser;
 use crate::services::block_revision_editor::{GridBlockRevisionCompactor, GridBlockRevisionEditor};
 use crate::services::persistence::block_index::BlockIndexCache;
-use crate::services::row::{block_from_row_orders, GridBlockSnapshot};
+use crate::services::row::{block_from_row_orders, make_row_from_row_rev, GridBlockSnapshot};
 use dashmap::DashMap;
 use flowy_error::FlowyResult;
 use flowy_grid_data_model::revision::{
@@ -110,20 +110,18 @@ impl GridBlockManager {
 
     pub async fn update_row<F>(&self, changeset: RowMetaChangeset, row_builder: F) -> FlowyResult<()>
     where
-        F: FnOnce(Arc<RowRevision>) -> Option<RowPB>,
+        F: FnOnce(Arc<RowRevision>) -> RowPB,
     {
         let editor = self.get_editor_from_row_id(&changeset.row_id).await?;
         let _ = editor.update_row(changeset.clone()).await?;
         match editor.get_row_rev(&changeset.row_id).await? {
             None => tracing::error!("Internal error: can't find the row with id: {}", changeset.row_id),
             Some(row_rev) => {
-                if let Some(row) = row_builder(row_rev.clone()) {
-                    let row_order = UpdatedRowPB::new(&row_rev, row);
-                    let block_order_changeset = GridBlockChangesetPB::update(&editor.block_id, vec![row_order]);
-                    let _ = self
-                        .notify_did_update_block(&editor.block_id, block_order_changeset)
-                        .await?;
-                }
+                let block_order_changeset =
+                    GridBlockChangesetPB::update(&editor.block_id, vec![row_builder(row_rev.clone())]);
+                let _ = self
+                    .notify_did_update_block(&editor.block_id, block_order_changeset)
+                    .await?;
             }
         }
         Ok(())
@@ -170,17 +168,16 @@ impl GridBlockManager {
         match editor.get_row_revs(Some(vec![Cow::Borrowed(row_id)])).await?.pop() {
             None => {}
             Some(row_rev) => {
+                let delete_row_id = row_rev.id.clone();
                 let insert_row = InsertedRowPB {
-                    block_id: row_rev.block_id.clone(),
-                    row_id: row_rev.id.clone(),
                     index: Some(to as i32),
-                    height: row_rev.height,
+                    row: make_row_from_row_rev(row_rev),
                 };
 
                 let notified_changeset = GridBlockChangesetPB {
                     block_id: editor.block_id.clone(),
                     inserted_rows: vec![insert_row],
-                    deleted_rows: vec![row_rev.id.clone()],
+                    deleted_rows: vec![delete_row_id],
                     ..Default::default()
                 };
 
@@ -195,7 +192,7 @@ impl GridBlockManager {
 
     pub async fn update_cell<F>(&self, changeset: CellChangesetPB, row_builder: F) -> FlowyResult<()>
     where
-        F: FnOnce(Arc<RowRevision>) -> Option<RowPB>,
+        F: FnOnce(Arc<RowRevision>) -> RowPB,
     {
         let row_changeset: RowMetaChangeset = changeset.clone().into();
         let _ = self.update_row(row_changeset, row_builder).await?;

+ 2 - 2
frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs

@@ -39,8 +39,8 @@ pub(crate) fn make_row_orders_from_row_revs(row_revs: &[Arc<RowRevision>]) -> Ve
     row_revs.iter().map(RowPB::from).collect::<Vec<_>>()
 }
 
-pub(crate) fn make_row_from_row_rev(row_rev: Arc<RowRevision>) -> Option<RowPB> {
-    make_rows_from_row_revs(&[row_rev]).pop()
+pub(crate) fn make_row_from_row_rev(row_rev: Arc<RowRevision>) -> RowPB {
+    make_rows_from_row_revs(&[row_rev]).pop().unwrap()
 }
 
 pub(crate) fn make_rows_from_row_revs(row_revs: &[Arc<RowRevision>]) -> Vec<RowPB> {