mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: setup GridCellContext fieldOnchanged callback
This commit is contained in:
parent
6d385877a9
commit
cffd8fbec6
@ -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();
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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) {
|
||||
|
@ -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));
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
));
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
));
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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(
|
||||
|
@ -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()));
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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';
|
||||
|
@ -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,
|
||||
|
@ -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]);
|
||||
|
Loading…
Reference in New Issue
Block a user