fix: setup GridCellContext fieldOnchanged callback

This commit is contained in:
appflowy 2022-04-24 23:20:28 +08:00
parent 6d385877a9
commit cffd8fbec6
14 changed files with 133 additions and 110 deletions

View File

@ -35,19 +35,6 @@ class GridCellContext<T> {
}) : _cellListener = CellListener(rowId: gridCell.rowId, fieldId: gridCell.field.id),
_cacheKey = GridCellCacheKey(objectId: gridCell.rowId, fieldId: gridCell.field.id) {
_cellDataNotifier = ValueNotifier(cellCache.get(cacheKey));
_cellListener.updateCellNotifier?.addPublishListener((result) {
result.fold(
(notification) => _loadData(),
(err) => Log.error(err),
);
});
_cellListener.start();
if (cellDataLoader.reloadOnFieldChanged) {
cellCache.addListener(cacheKey, () => reloadCellData());
}
}
String get gridId => gridCell.gridId;
@ -64,6 +51,27 @@ class GridCellContext<T> {
GridCellCacheKey get cacheKey => _cacheKey;
void startListening({required void Function(T) onCellChanged}) {
_cellListener.updateCellNotifier?.addPublishListener((result) {
result.fold(
(notification) => _loadData(),
(err) => Log.error(err),
);
});
_cellListener.start();
if (cellDataLoader.reloadOnFieldChanged) {
cellCache.addListener(cacheKey, () => reloadCellData());
}
_cellDataNotifier.addListener(() {
final value = _cellDataNotifier.value;
if (value is T) {
onCellChanged(value);
}
});
}
T? getCellData() {
final data = cellCache.get(cacheKey);
if (data == null) {
@ -96,15 +104,6 @@ class GridCellContext<T> {
});
}
void onCellChanged(void Function(T) callback) {
_cellDataNotifier.addListener(() {
final value = _cellDataNotifier.value;
if (value is T) {
callback(value);
}
});
}
void dispose() {
_delayOperation?.cancel();
}

View File

@ -37,11 +37,11 @@ class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
}
void _startListening() {
cellContext.onCellChanged((cell) {
cellContext.startListening(onCellChanged: ((cell) {
if (!isClosed) {
add(CheckboxCellEvent.didReceiveCellUpdate(cell));
}
});
}));
}
void _updateCellData() {

View File

@ -39,11 +39,13 @@ class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
}
void _startListening() {
cellContext.onCellChanged((cell) {
if (!isClosed) {
add(DateCellEvent.didReceiveCellUpdate(cell));
}
});
cellContext.startListening(
onCellChanged: ((cell) {
if (!isClosed) {
add(DateCellEvent.didReceiveCellUpdate(cell));
}
}),
);
}
void _updateCellData(DateTime day) {

View File

@ -41,11 +41,13 @@ class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
}
void _startListening() {
cellContext.onCellChanged((cell) {
if (!isClosed) {
add(NumberCellEvent.didReceiveCellUpdate(cell));
}
});
cellContext.startListening(
onCellChanged: ((cell) {
if (!isClosed) {
add(NumberCellEvent.didReceiveCellUpdate(cell));
}
}),
);
}
}

View File

@ -36,14 +36,16 @@ class SelectionCellBloc extends Bloc<SelectionCellEvent, SelectionCellState> {
}
void _startListening() {
cellContext.onCellChanged((selectOptionContext) {
if (!isClosed) {
add(SelectionCellEvent.didReceiveOptions(
selectOptionContext.options,
selectOptionContext.selectOptions,
));
}
});
cellContext.startListening(
onCellChanged: ((selectOptionContext) {
if (!isClosed) {
add(SelectionCellEvent.didReceiveOptions(
selectOptionContext.options,
selectOptionContext.selectOptions,
));
}
}),
);
}
}

View File

@ -82,14 +82,16 @@ class SelectOptionEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOptionE
}
void _startListening() {
cellContext.onCellChanged((selectOptionContext) {
if (!isClosed) {
add(SelectOptionEditorEvent.didReceiveOptions(
selectOptionContext.options,
selectOptionContext.selectOptions,
));
}
});
cellContext.startListening(
onCellChanged: ((selectOptionContext) {
if (!isClosed) {
add(SelectOptionEditorEvent.didReceiveOptions(
selectOptionContext.options,
selectOptionContext.selectOptions,
));
}
}),
);
}
}

View File

@ -41,11 +41,13 @@ class TextCellBloc extends Bloc<TextCellEvent, TextCellState> {
}
void _startListening() {
cellContext.onCellChanged((cell) {
if (!isClosed) {
add(TextCellEvent.didReceiveCellUpdate(cell));
}
});
cellContext.startListening(
onCellChanged: ((cell) {
if (!isClosed) {
add(TextCellEvent.didReceiveCellUpdate(cell));
}
}),
);
}
}

View File

@ -88,7 +88,7 @@ class GridBloc extends Bloc<GridEvent, GridState> {
() => result.fold(
(fields) {
fieldCache.fields = fields.items;
rowCache.updateWithBlock(grid.blockOrders);
rowCache.resetRows(grid.blockOrders);
emit(state.copyWith(
grid: Some(grid),

View File

@ -17,7 +17,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
required GridRowCache rowCache,
}) : _rowService = RowService(gridId: rowData.gridId, rowId: rowData.rowId),
_rowCache = rowCache,
super(RowState.initial(rowData, rowCache.loadCellData(rowData.rowId))) {
super(RowState.initial(rowData, rowCache.loadGridCells(rowData.rowId))) {
on<RowEvent>(
(event, emit) async {
await event.map(

View File

@ -48,7 +48,7 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
}
Future<void> _loadCellData() async {
final cellDataMap = _rowCache.loadCellData(rowData.rowId);
final cellDataMap = _rowCache.loadGridCells(rowData.rowId);
if (!isClosed) {
add(RowDetailEvent.didReceiveCellDatas(cellDataMap.values.toList()));
}

View File

@ -22,14 +22,13 @@ abstract class GridRowFieldDelegate {
class GridRowCache {
final String gridId;
final RowsNotifier _rowNotifier;
final RowsNotifier _rowsNotifier;
final GridRowListener _rowsListener;
final GridRowFieldDelegate _fieldDelegate;
List<GridRow> get clonedRows => _rowNotifier.clonedRows;
List<GridRow> get clonedRows => _rowsNotifier.clonedRows;
GridRowCache({required this.gridId, required GridRowFieldDelegate fieldDelegate})
: _rowNotifier = RowsNotifier(
: _rowsNotifier = RowsNotifier(
rowBuilder: (rowOrder) {
return GridRow(
gridId: gridId,
@ -42,16 +41,16 @@ class GridRowCache {
_rowsListener = GridRowListener(gridId: gridId),
_fieldDelegate = fieldDelegate {
//
fieldDelegate.onFieldChanged(() => _rowNotifier.fieldDidChange());
fieldDelegate.onFieldChanged(() => _rowsNotifier.fieldDidChange());
// listen on the row update
_rowsListener.rowsUpdateNotifier.addPublishListener((result) {
result.fold(
(changesets) {
for (final changeset in changesets) {
_rowNotifier.deleteRows(changeset.deletedRows);
_rowNotifier.insertRows(changeset.insertedRows);
_rowNotifier.updateRows(changeset.updatedRows);
_rowsNotifier.deleteRows(changeset.deletedRows);
_rowsNotifier.insertRows(changeset.insertedRows);
_rowsNotifier.updateRows(changeset.updatedRows);
}
},
(err) => Log.error(err),
@ -62,14 +61,14 @@ class GridRowCache {
Future<void> dispose() async {
await _rowsListener.stop();
_rowNotifier.dispose();
_rowsNotifier.dispose();
}
void addListener({
void Function(List<GridRow>, GridRowChangeReason)? onChanged,
bool Function()? listenWhen,
}) {
_rowNotifier.addListener(() {
_rowsNotifier.addListener(() {
if (onChanged == null) {
return;
}
@ -78,7 +77,7 @@ class GridRowCache {
return;
}
onChanged(clonedRows, _rowNotifier._changeReason);
onChanged(clonedRows, _rowsNotifier._changeReason);
});
}
@ -87,7 +86,7 @@ class GridRowCache {
void Function(GridCellMap)? onUpdated,
bool Function()? listenWhen,
}) {
listenrHandler() {
listenrHandler() async {
if (onUpdated == null) {
return;
}
@ -97,14 +96,14 @@ class GridRowCache {
}
notify() {
final row = _rowNotifier.rowDataWithId(rowId);
final row = _rowsNotifier.rowDataWithId(rowId);
if (row != null) {
final GridCellMap cellDataMap = _makeCellDataMap(rowId, row);
final GridCellMap cellDataMap = _makeGridCells(rowId, row);
onUpdated(cellDataMap);
}
}
_rowNotifier._changeReason.whenOrNull(
_rowsNotifier._changeReason.whenOrNull(
update: (indexs) {
if (indexs[rowId] != null) {
notify();
@ -114,11 +113,40 @@ class GridRowCache {
);
}
_rowNotifier.addListener(listenrHandler);
_rowsNotifier.addListener(listenrHandler);
return listenrHandler;
}
GridCellMap _makeCellDataMap(String rowId, Row? row) {
void removeRowListener(VoidCallback callback) {
_rowsNotifier.removeListener(callback);
}
GridCellMap loadGridCells(String rowId) {
final Row? data = _rowsNotifier.rowDataWithId(rowId);
if (data == null) {
_loadRow(rowId);
}
return _makeGridCells(rowId, data);
}
void resetRows(List<GridBlockOrder> blocks) {
final rowOrders = blocks.expand((block) => block.rowOrders).toList();
_rowsNotifier.reset(rowOrders);
}
Future<void> _loadRow(String rowId) async {
final payload = RowIdentifierPayload.create()
..gridId = gridId
..rowId = rowId;
final result = await GridEventGetRow(payload).send();
result.fold(
(rowData) => _rowsNotifier.rowData = rowData,
(err) => Log.error(err),
);
}
GridCellMap _makeGridCells(String rowId, Row? row) {
var cellDataMap = GridCellMap.new();
for (final field in _fieldDelegate.fields) {
if (field.visibility) {
@ -132,33 +160,6 @@ class GridRowCache {
}
return cellDataMap;
}
void removeRowListener(VoidCallback callback) {
_rowNotifier.removeListener(callback);
}
GridCellMap loadCellData(String rowId) {
final Row? data = _rowNotifier.rowDataWithId(rowId);
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),
);
});
}
return _makeCellDataMap(rowId, data);
}
void updateWithBlock(List<GridBlockOrder> blocks) {
final rowOrders = blocks.expand((block) => block.rowOrders).toList();
_rowNotifier.reset(rowOrders);
}
}
class RowsNotifier extends ChangeNotifier {

View File

@ -2,7 +2,6 @@ import 'package:app_flowy/workspace/application/grid/cell/cell_service.dart';
import 'package:app_flowy/workspace/application/grid/cell/select_option_service.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType;
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
import 'package:flutter/widgets.dart';
import 'checkbox_cell.dart';
import 'date_cell.dart';

View File

@ -96,6 +96,12 @@ impl ClientGridBlockMetaEditor {
Ok(())
}
pub async fn get_row_meta(&self, row_id: &str) -> FlowyResult<Option<Arc<RowMeta>>> {
let row_ids = vec![Cow::Borrowed(row_id)];
let row_meta = self.get_row_metas(Some(row_ids)).await?.pop();
Ok(row_meta)
}
pub async fn get_row_metas<T>(&self, row_ids: Option<Vec<Cow<'_, T>>>) -> FlowyResult<Vec<Arc<RowMeta>>>
where
T: AsRef<str> + ToOwned + ?Sized,
@ -113,6 +119,11 @@ impl ClientGridBlockMetaEditor {
Ok(cell_metas)
}
pub async fn get_row_order(&self, row_id: &str) -> FlowyResult<Option<RowOrder>> {
let row_ids = Some(vec![Cow::Borrowed(row_id)]);
Ok(self.get_row_orders(row_ids).await?.pop())
}
pub async fn get_row_orders<T>(&self, row_ids: Option<Vec<Cow<'_, T>>>) -> FlowyResult<Vec<RowOrder>>
where
T: AsRef<str> + ToOwned + ?Sized,

View File

@ -119,11 +119,15 @@ impl GridBlockMetaEditorManager {
let row_id = row_id.to_owned();
let block_id = self.persistence.get_block_id(&row_id)?;
let editor = self.get_editor(&block_id).await?;
let row_orders = editor.get_row_orders(Some(vec![Cow::Borrowed(&row_id)])).await?;
let _ = editor.delete_rows(vec![Cow::Borrowed(&row_id)]).await?;
let _ = self
.notify_did_update_block(GridRowsChangeset::delete(&block_id, row_orders))
.await?;
match editor.get_row_order(&row_id).await? {
None => {}
Some(row_order) => {
let _ = editor.delete_rows(vec![Cow::Borrowed(&row_id)]).await?;
let _ = self
.notify_did_update_block(GridRowsChangeset::delete(&block_id, vec![row_order]))
.await?;
}
}
Ok(())
}
@ -231,8 +235,7 @@ impl GridBlockMetaEditorManager {
async fn notify_did_update_block_row(&self, row_id: &str) -> FlowyResult<()> {
let editor = self.get_editor_from_row_id(row_id).await?;
let row_ids = Some(vec![Cow::Borrowed(&row_id)]);
match editor.get_row_orders(row_ids).await?.pop() {
match editor.get_row_order(row_id).await? {
None => {}
Some(row_order) => {
let block_order_changeset = GridRowsChangeset::update(&editor.block_id, vec![row_order]);