chore: reuse widget while inserting row

This commit is contained in:
appflowy 2022-04-22 20:39:49 +08:00
parent bf93376cf3
commit fa7097587f
7 changed files with 48 additions and 59 deletions

View File

@ -180,14 +180,14 @@ class GridRowDataDelegateAdaptor extends GridRowDataDelegate {
}
@override
CellDataMap buildCellDataMap(Row rowData) {
CellDataMap buildCellDataMap(String rowId, Row? rowData) {
var map = CellDataMap.new();
for (final field in fields) {
if (field.visibility) {
map[field.id] = GridCell(
rowId: rowData.id,
rowId: rowId,
gridId: _cache.gridId,
cell: rowData.cellByFieldId[field.id],
cell: rowData?.cellByFieldId[field.id],
field: field,
);
}

View File

@ -17,19 +17,18 @@ class RowBloc extends Bloc<RowEvent, RowState> {
required GridRowCache rowCache,
}) : _rowService = RowService(gridId: rowData.gridId, rowId: rowData.rowId),
_rowCache = rowCache,
super(RowState.initial(rowData)) {
super(RowState.initial(rowData, rowCache.loadCellData(rowData.rowId))) {
on<RowEvent>(
(event, emit) async {
await event.map(
initial: (_InitialRow value) async {
await _startListening();
await _loadRow(emit);
},
createRow: (_CreateRow value) {
_rowService.createRow();
},
didReceiveCellDatas: (_DidReceiveCellDatas value) async {
emit(state.copyWith(cellDataMap: Some(value.cellData)));
emit(state.copyWith(cellDataMap: value.cellData));
},
);
},
@ -41,6 +40,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
if (_rowListenFn != null) {
_rowCache.removeRowListener(_rowListenFn!);
}
return super.close();
}
@ -51,15 +51,6 @@ class RowBloc extends Bloc<RowEvent, RowState> {
listenWhen: () => !isClosed,
);
}
Future<void> _loadRow(Emitter<RowState> emit) async {
final data = _rowCache.loadCellData(state.rowData.rowId);
data.foldRight(null, (cellDatas, _) {
if (!isClosed) {
add(RowEvent.didReceiveCellDatas(cellDatas));
}
});
}
}
@freezed
@ -73,11 +64,11 @@ class RowEvent with _$RowEvent {
class RowState with _$RowState {
const factory RowState({
required GridRow rowData,
required Option<CellDataMap> cellDataMap,
required CellDataMap cellDataMap,
}) = _RowState;
factory RowState.initial(GridRow rowData) => RowState(
factory RowState.initial(GridRow rowData, CellDataMap cellDataMap) => RowState(
rowData: rowData,
cellDataMap: none(),
cellDataMap: cellDataMap,
);
}

View File

@ -47,12 +47,10 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
}
Future<void> _loadCellData() async {
final data = _rowCache.loadCellData(rowData.rowId);
data.foldRight(null, (cellDataMap, _) {
if (!isClosed) {
add(RowDetailEvent.didReceiveCellDatas(cellDataMap.values.toList()));
}
});
final cellDataMap = _rowCache.loadCellData(rowData.rowId);
if (!isClosed) {
add(RowDetailEvent.didReceiveCellDatas(cellDataMap.values.toList()));
}
}
}

View File

@ -18,7 +18,7 @@ typedef CellDataMap = LinkedHashMap<String, GridCell>;
abstract class GridRowDataDelegate {
UnmodifiableListView<Field> get fields;
GridRow buildGridRow(RowOrder rowOrder);
CellDataMap buildCellDataMap(Row rowData);
CellDataMap buildCellDataMap(String rowId, Row? rowData);
void onFieldChanged(FieldDidUpdateCallback callback);
}
@ -92,7 +92,7 @@ class GridRowCache {
notify() {
final row = _rowNotifier.rowDataWithId(rowId);
if (row != null) {
final cellDataMap = _dataDelegate.buildCellDataMap(row);
final cellDataMap = _dataDelegate.buildCellDataMap(rowId, row);
onUpdated(cellDataMap);
}
}
@ -115,23 +115,22 @@ class GridRowCache {
_rowNotifier.removeListener(callback);
}
Option<CellDataMap> loadCellData(String rowId) {
CellDataMap loadCellData(String rowId) {
final Row? data = _rowNotifier.rowDataWithId(rowId);
if (data != null) {
return Some(_dataDelegate.buildCellDataMap(data));
if (data == null) {
final payload = RowIdentifierPayload.create()
..gridId = gridId
..rowId = rowId;
GridEventGetRow(payload).send().then((result) {
result.fold(
(rowData) => _rowNotifier.rowData = rowData,
(err) => Log.error(err),
);
});
}
final payload = RowIdentifierPayload.create()
..gridId = gridId
..rowId = rowId;
GridEventGetRow(payload).send().then((result) {
result.fold(
(rowData) => _rowNotifier.rowData = rowData,
(err) => Log.error(err),
);
});
return none();
return _dataDelegate.buildCellDataMap(rowId, data);
}
void updateWithBlock(List<GridBlockOrder> blocks) {
@ -331,6 +330,10 @@ class GridCell with _$GridCell {
required Field field,
Cell? cell,
}) = _GridCell;
ValueKey key() {
return ValueKey(rowId + (cell?.fieldId ?? ""));
}
}
typedef InsertedIndexs = List<InsertedIndex>;

View File

@ -213,7 +213,7 @@ class _GridRowsState extends State<_GridRows> {
key: _key,
initialItemCount: context.read<GridBloc>().state.rows.length,
itemBuilder: (BuildContext context, int index, Animation<double> animation) {
final rowData = context.read<GridBloc>().state.rows[index];
final GridRow rowData = context.read<GridBloc>().state.rows[index];
return _renderRow(context, rowData, animation);
},
);

View File

@ -9,7 +9,7 @@ import 'selection_cell/selection_cell.dart';
import 'text_cell.dart';
GridCellWidget buildGridCell(GridCell cellData, {GridCellStyle? style}) {
final key = ValueKey(cellData.field.id + cellData.rowId);
final key = cellData.key();
switch (cellData.field.fieldType) {
case FieldType.Checkbox:
return CheckboxCell(cellData: cellData, key: key);

View File

@ -164,24 +164,21 @@ class _RowCells extends StatelessWidget {
);
}
List<Widget> _makeCells(Option<CellDataMap> data) {
return data.fold(
() => [],
(cellDataMap) => cellDataMap.values.map(
(cellData) {
Widget? expander;
if (cellData.field.isPrimary) {
expander = _CellExpander(onExpand: onExpand);
}
List<Widget> _makeCells(CellDataMap cellDataMap) {
return cellDataMap.values.map(
(cellData) {
Widget? expander;
if (cellData.field.isPrimary) {
expander = _CellExpander(onExpand: onExpand);
}
return CellContainer(
width: cellData.field.width.toDouble(),
child: buildGridCell(cellData),
expander: expander,
);
},
).toList(),
);
return CellContainer(
width: cellData.field.width.toDouble(),
child: buildGridCell(cellData),
expander: expander,
);
},
).toList();
}
}