Browse Source

chore: do not build the cell if its fieldId equal to the corresponding group field id

appflowy 2 years ago
parent
commit
aba0f946dd

+ 20 - 13
frontend/app_flowy/lib/plugins/board/application/board_bloc.dart

@@ -165,7 +165,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
           return AFBoardColumnData(
             id: group.groupId,
             name: group.desc,
-            items: _buildRows(group.rows),
+            items: _buildRows(group),
             customData: group,
           );
         }).toList();
@@ -196,9 +196,9 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
     );
   }
 
-  List<AFColumnItem> _buildRows(List<RowPB> rows) {
-    final items = rows.map((row) {
-      return BoardColumnItem(row: row);
+  List<AFColumnItem> _buildRows(GroupPB group) {
+    final items = group.rows.map((row) {
+      return BoardColumnItem(row: row, fieldId: group.fieldId);
     }).toList();
 
     return <AFColumnItem>[...items];
@@ -284,7 +284,9 @@ class GridFieldEquatable extends Equatable {
 class BoardColumnItem extends AFColumnItem {
   final RowPB row;
 
-  BoardColumnItem({required this.row});
+  final String fieldId;
+
+  BoardColumnItem({required this.row, required this.fieldId});
 
   @override
   String get id => row.id;
@@ -301,22 +303,27 @@ class GroupControllerDelegateImpl extends GroupControllerDelegate {
   GroupControllerDelegateImpl(this.controller);
 
   @override
-  void insertRow(String groupId, RowPB row, int? index) {
-    final item = BoardColumnItem(row: row);
+  void insertRow(GroupPB group, RowPB row, int? index) {
+    final item = BoardColumnItem(row: row, fieldId: group.fieldId);
     if (index != null) {
-      controller.insertColumnItem(groupId, index, item);
+      controller.insertColumnItem(group.groupId, index, item);
     } else {
-      controller.addColumnItem(groupId, item);
+      controller.addColumnItem(group.groupId, item);
     }
   }
 
   @override
-  void removeRow(String groupId, String rowId) {
-    controller.removeColumnItem(groupId, rowId);
+  void removeRow(GroupPB group, String rowId) {
+    controller.removeColumnItem(group.groupId, rowId);
   }
 
   @override
-  void updateRow(String groupId, RowPB row) {
-    controller.updateColumnItem(groupId, BoardColumnItem(row: row));
+  void updateRow(GroupPB group, RowPB row) {
+    controller.updateColumnItem(
+        group.groupId,
+        BoardColumnItem(
+          row: row,
+          fieldId: group.fieldId,
+        ));
   }
 }

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

@@ -4,7 +4,6 @@ import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
 import 'package:app_flowy/plugins/grid/application/row/row_service.dart';
 import 'package:equatable/equatable.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'dart:async';
@@ -14,10 +13,12 @@ import 'card_data_controller.dart';
 part 'card_bloc.freezed.dart';
 
 class BoardCardBloc extends Bloc<BoardCardEvent, BoardCardState> {
+  final String fieldId;
   final RowFFIService _rowService;
   final CardDataController _dataController;
 
   BoardCardBloc({
+    required this.fieldId,
     required String gridId,
     required CardDataController dataController,
   })  : _rowService = RowFFIService(
@@ -25,22 +26,22 @@ class BoardCardBloc extends Bloc<BoardCardEvent, BoardCardState> {
           blockId: dataController.rowPB.blockId,
         ),
         _dataController = dataController,
-        super(BoardCardState.initial(
-            dataController.rowPB, dataController.loadData())) {
+        super(
+          BoardCardState.initial(
+            dataController.rowPB,
+            _makeCells(fieldId, dataController.loadData()),
+          ),
+        ) {
     on<BoardCardEvent>(
       (event, emit) async {
-        await event.map(
-          initial: (_InitialRow value) async {
+        await event.when(
+          initial: () async {
             await _startListening();
           },
-          didReceiveCells: (_DidReceiveCells value) async {
-            final cells = value.gridCellMap.values
-                .map((e) => GridCellEquatable(e.field))
-                .toList();
+          didReceiveCells: (cells, reason) async {
             emit(state.copyWith(
-              gridCellMap: value.gridCellMap,
-              cells: UnmodifiableListView(cells),
-              changeReason: value.reason,
+              cells: cells,
+              changeReason: reason,
             ));
           },
         );
@@ -58,7 +59,7 @@ class BoardCardBloc extends Bloc<BoardCardEvent, BoardCardState> {
     return RowInfo(
       gridId: _rowService.gridId,
       fields: UnmodifiableListView(
-        state.cells.map((cell) => cell._field).toList(),
+        state.cells.map((cell) => cell.identifier.field).toList(),
       ),
       rowPB: state.rowPB,
     );
@@ -66,8 +67,9 @@ class BoardCardBloc extends Bloc<BoardCardEvent, BoardCardState> {
 
   Future<void> _startListening() async {
     _dataController.addListener(
-      onRowChanged: (cells, reason) {
+      onRowChanged: (cellMap, reason) {
         if (!isClosed) {
+          final cells = _makeCells(fieldId, cellMap);
           add(BoardCardEvent.didReceiveCells(cells, reason));
         }
       },
@@ -75,42 +77,49 @@ class BoardCardBloc extends Bloc<BoardCardEvent, BoardCardState> {
   }
 }
 
+UnmodifiableListView<BoardCellEquatable> _makeCells(
+    String fieldId, GridCellMap originalCellMap) {
+  List<BoardCellEquatable> cells = [];
+  for (final entry in originalCellMap.entries) {
+    if (entry.value.fieldId != fieldId) {
+      cells.add(BoardCellEquatable(entry.value));
+    }
+  }
+  return UnmodifiableListView(cells);
+}
+
 @freezed
 class BoardCardEvent with _$BoardCardEvent {
   const factory BoardCardEvent.initial() = _InitialRow;
   const factory BoardCardEvent.didReceiveCells(
-      GridCellMap gridCellMap, RowsChangedReason reason) = _DidReceiveCells;
+    UnmodifiableListView<BoardCellEquatable> cells,
+    RowsChangedReason reason,
+  ) = _DidReceiveCells;
 }
 
 @freezed
 class BoardCardState with _$BoardCardState {
   const factory BoardCardState({
     required RowPB rowPB,
-    required GridCellMap gridCellMap,
-    required UnmodifiableListView<GridCellEquatable> cells,
+    required UnmodifiableListView<BoardCellEquatable> cells,
     RowsChangedReason? changeReason,
   }) = _BoardCardState;
 
-  factory BoardCardState.initial(RowPB rowPB, GridCellMap cellDataMap) =>
-      BoardCardState(
-        rowPB: rowPB,
-        gridCellMap: cellDataMap,
-        cells: UnmodifiableListView(
-          cellDataMap.values.map((e) => GridCellEquatable(e.field)).toList(),
-        ),
-      );
+  factory BoardCardState.initial(
+          RowPB rowPB, UnmodifiableListView<BoardCellEquatable> cells) =>
+      BoardCardState(rowPB: rowPB, cells: cells);
 }
 
-class GridCellEquatable extends Equatable {
-  final FieldPB _field;
+class BoardCellEquatable extends Equatable {
+  final GridCellIdentifier identifier;
 
-  const GridCellEquatable(FieldPB field) : _field = field;
+  const BoardCellEquatable(this.identifier);
 
   @override
   List<Object?> get props => [
-        _field.id,
-        _field.fieldType,
-        _field.visibility,
-        _field.width,
+        identifier.field.id,
+        identifier.field.fieldType,
+        identifier.field.visibility,
+        identifier.field.width,
       ];
 }

+ 6 - 6
frontend/app_flowy/lib/plugins/board/application/group_controller.dart

@@ -7,9 +7,9 @@ import 'group_listener.dart';
 typedef OnGroupError = void Function(FlowyError);
 
 abstract class GroupControllerDelegate {
-  void removeRow(String groupId, String rowId);
-  void insertRow(String groupId, RowPB row, int? index);
-  void updateRow(String groupId, RowPB row);
+  void removeRow(GroupPB group, String rowId);
+  void insertRow(GroupPB group, RowPB row, int? index);
+  void updateRow(GroupPB group, RowPB row);
 }
 
 class GroupController {
@@ -37,7 +37,7 @@ class GroupController {
         (GroupChangesetPB changeset) {
           for (final deletedRow in changeset.deletedRows) {
             group.rows.removeWhere((rowPB) => rowPB.id == deletedRow);
-            delegate.removeRow(group.groupId, deletedRow);
+            delegate.removeRow(group, deletedRow);
           }
 
           for (final insertedRow in changeset.insertedRows) {
@@ -51,7 +51,7 @@ class GroupController {
             }
 
             delegate.insertRow(
-              group.groupId,
+              group,
               insertedRow.row,
               index,
             );
@@ -66,7 +66,7 @@ class GroupController {
               group.rows[index] = updatedRow;
             }
 
-            delegate.updateRow(group.groupId, updatedRow);
+            delegate.updateRow(group, updatedRow);
           }
         },
         (err) => Log.error(err),

+ 5 - 2
frontend/app_flowy/lib/plugins/board/presentation/board_page.dart

@@ -73,7 +73,8 @@ class _BoardContentState extends State<BoardContent> {
   @override
   Widget build(BuildContext context) {
     return BlocBuilder<BoardBloc, BoardState>(
-      buildWhen: (previous, current) => previous.groupIds != current.groupIds,
+      buildWhen: (previous, current) =>
+          previous.groupIds.length != current.groupIds.length,
       builder: (context, state) {
         return Container(
           color: Colors.white,
@@ -159,7 +160,8 @@ class _BoardContentState extends State<BoardContent> {
     AFBoardColumnData column,
     AFColumnItem columnItem,
   ) {
-    final rowPB = (columnItem as BoardColumnItem).row;
+    final boardColumnItem = columnItem as BoardColumnItem;
+    final rowPB = boardColumnItem.row;
     final rowCache = context.read<BoardBloc>().getRowCache(rowPB.blockId);
 
     /// Return placeholder widget if the rowCache is null.
@@ -186,6 +188,7 @@ class _BoardContentState extends State<BoardContent> {
       child: BoardCard(
         gridId: gridId,
         groupId: column.id,
+        fieldId: boardColumnItem.fieldId,
         isEditing: isEditing,
         cellBuilder: cellBuilder,
         dataController: cardController,

+ 3 - 2
frontend/app_flowy/lib/plugins/board/presentation/card/board_select_option_cell.dart

@@ -35,8 +35,9 @@ class _BoardSelectOptionCellState extends State<BoardSelectOptionCell> {
     return BlocProvider.value(
       value: _cellBloc,
       child: BlocBuilder<BoardSelectOptionCellBloc, BoardSelectOptionCellState>(
-        buildWhen: (previous, current) =>
-            previous.selectedOptions != current.selectedOptions,
+        buildWhen: (previous, current) {
+          return previous.selectedOptions != current.selectedOptions;
+        },
         builder: (context, state) {
           if (state.selectedOptions
               .where((element) => element.id == widget.groupId)

+ 16 - 4
frontend/app_flowy/lib/plugins/board/presentation/card/card.dart

@@ -15,6 +15,7 @@ typedef OnEndEditing = void Function(String rowId);
 class BoardCard extends StatefulWidget {
   final String gridId;
   final String groupId;
+  final String fieldId;
   final bool isEditing;
   final CardDataController dataController;
   final BoardCellBuilder cellBuilder;
@@ -24,6 +25,7 @@ class BoardCard extends StatefulWidget {
   const BoardCard({
     required this.gridId,
     required this.groupId,
+    required this.fieldId,
     required this.isEditing,
     required this.dataController,
     required this.cellBuilder,
@@ -43,6 +45,7 @@ class _BoardCardState extends State<BoardCard> {
   void initState() {
     _cardBloc = BoardCardBloc(
       gridId: widget.gridId,
+      fieldId: widget.fieldId,
       dataController: widget.dataController,
     )..add(const BoardCardEvent.initial());
     super.initState();
@@ -53,6 +56,9 @@ class _BoardCardState extends State<BoardCard> {
     return BlocProvider.value(
       value: _cardBloc,
       child: BlocBuilder<BoardCardBloc, BoardCardState>(
+        buildWhen: (previous, current) {
+          return previous.cells.length != current.cells.length;
+        },
         builder: (context, state) {
           return BoardCardContainer(
             accessoryBuilder: (context) {
@@ -62,7 +68,10 @@ class _BoardCardState extends State<BoardCard> {
               widget.openCard(context);
             },
             child: Column(
-              children: _makeCells(context, state.gridCellMap),
+              children: _makeCells(
+                context,
+                state.cells.map((cell) => cell.identifier).toList(),
+              ),
             ),
           );
         },
@@ -70,9 +79,12 @@ class _BoardCardState extends State<BoardCard> {
     );
   }
 
-  List<Widget> _makeCells(BuildContext context, GridCellMap cellMap) {
-    return cellMap.values.map(
-      (cellId) {
+  List<Widget> _makeCells(
+    BuildContext context,
+    List<GridCellIdentifier> cells,
+  ) {
+    return cells.map(
+      (GridCellIdentifier cellId) {
         final child = widget.cellBuilder.buildCell(widget.groupId, cellId);
         return Padding(
           padding: const EdgeInsets.only(left: 4, right: 4, top: 6),

+ 25 - 26
frontend/rust-lib/flowy-grid/src/services/grid_editor.rs

@@ -18,7 +18,7 @@ use flowy_sync::client_grid::{GridRevisionChangeset, GridRevisionPad, JsonDeseri
 use flowy_sync::entities::revision::Revision;
 use flowy_sync::errors::CollaborateResult;
 use flowy_sync::util::make_text_delta_from_revisions;
-use lib_infra::future::FutureResult;
+use lib_infra::future::{wrap_future, FutureResult};
 
 use std::collections::HashMap;
 use std::sync::Arc;
@@ -591,34 +591,33 @@ impl GridRevisionEditor {
         match self.block_manager.get_row_rev(&from_row_id).await? {
             None => tracing::warn!("Move row failed, can not find the row:{}", from_row_id),
             Some(row_rev) => {
-                if let Some(row_changeset) = self
-                    .view_manager
-                    .move_group_row(row_rev, to_group_id, to_row_id.clone())
-                    .await
-                {
-                    tracing::trace!("Move group row cause row data changed: {:?}", row_changeset);
-
-                    let cell_changesets = row_changeset
-                        .cell_by_field_id
-                        .into_iter()
-                        .map(|(field_id, cell_rev)| CellChangesetPB {
-                            grid_id: view_id.clone(),
-                            row_id: row_changeset.row_id.clone(),
-                            field_id,
-                            content: cell_rev.data,
+                let block_manager = self.block_manager.clone();
+                self.view_manager
+                    .move_group_row(row_rev, to_group_id, to_row_id.clone(), |row_changeset| {
+                        wrap_future(async move {
+                            tracing::trace!("Move group row cause row data changed: {:?}", row_changeset);
+                            let cell_changesets = row_changeset
+                                .cell_by_field_id
+                                .into_iter()
+                                .map(|(field_id, cell_rev)| CellChangesetPB {
+                                    grid_id: view_id.clone(),
+                                    row_id: row_changeset.row_id.clone(),
+                                    field_id,
+                                    content: cell_rev.data,
+                                })
+                                .collect::<Vec<CellChangesetPB>>();
+
+                            for cell_changeset in cell_changesets {
+                                match block_manager.update_cell(cell_changeset).await {
+                                    Ok(_) => {}
+                                    Err(e) => tracing::error!("Apply cell changeset error:{:?}", e),
+                                }
+                            }
                         })
-                        .collect::<Vec<CellChangesetPB>>();
-
-                    for cell_changeset in cell_changesets {
-                        match self.block_manager.update_cell(cell_changeset).await {
-                            Ok(_) => {}
-                            Err(e) => tracing::error!("Apply cell changeset error:{:?}", e),
-                        }
-                    }
-                }
+                    })
+                    .await?;
             }
         }
-
         Ok(())
     }
 

+ 5 - 6
frontend/rust-lib/flowy-grid/src/services/grid_view_editor.rs

@@ -140,8 +140,8 @@ impl GridViewRevisionEditor {
         row_changeset: &mut RowChangeset,
         to_group_id: &str,
         to_row_id: Option<String>,
-    ) {
-        if let Some(changesets) = self
+    ) -> Vec<GroupChangesetPB> {
+        match self
             .group_service
             .write()
             .await
@@ -150,9 +150,8 @@ impl GridViewRevisionEditor {
             })
             .await
         {
-            for changeset in changesets {
-                self.notify_did_update_group(changeset).await;
-            }
+            None => vec![],
+            Some(changesets) => changesets,
         }
     }
     /// Only call once after grid view editor initialized
@@ -266,7 +265,7 @@ impl GridViewRevisionEditor {
         Ok(())
     }
 
-    async fn notify_did_update_group(&self, changeset: GroupChangesetPB) {
+    pub async fn notify_did_update_group(&self, changeset: GroupChangesetPB) {
         send_dart_notification(&changeset.group_id, GridNotification::DidUpdateGroup)
             .payload(changeset)
             .send();

+ 13 - 9
frontend/rust-lib/flowy-grid/src/services/grid_view_manager.rs

@@ -134,19 +134,23 @@ impl GridViewManager {
         row_rev: Arc<RowRevision>,
         to_group_id: String,
         to_row_id: Option<String>,
-    ) -> Option<RowChangeset> {
+        with_row_changeset: impl FnOnce(RowChangeset) -> AFFuture<()>,
+    ) -> FlowyResult<()> {
         let mut row_changeset = RowChangeset::new(row_rev.id.clone());
-        for view_editor in self.view_editors.iter() {
-            view_editor
-                .move_group_row(&row_rev, &mut row_changeset, &to_group_id, to_row_id.clone())
-                .await;
+        let view_editor = self.get_default_view_editor().await?;
+        let group_changesets = view_editor
+            .move_group_row(&row_rev, &mut row_changeset, &to_group_id, to_row_id.clone())
+            .await;
+
+        if row_changeset.is_empty() == false {
+            with_row_changeset(row_changeset).await;
         }
 
-        if row_changeset.is_empty() {
-            None
-        } else {
-            Some(row_changeset)
+        for group_changeset in group_changesets {
+            view_editor.notify_did_update_group(group_changeset).await;
         }
+
+        Ok(())
     }
 
     pub(crate) async fn did_update_field(&self, field_id: &str) -> FlowyResult<()> {