chore: listen on row update

This commit is contained in:
appflowy 2022-04-05 22:46:23 +08:00
parent 2607822412
commit c7a3bb73b9
9 changed files with 94 additions and 83 deletions

View File

@ -80,7 +80,7 @@ class GridBlockListener {
void _handleObservableType(GridNotification ty, Either<Uint8List, FlowyError> result) {
switch (ty) {
case GridNotification.DidUpdateRow:
case GridNotification.DidUpdateBlock:
result.fold(
(payload) => blockUpdateNotifier.value = left([GridBlockOrder.fromBuffer(payload)]),
(error) => blockUpdateNotifier.value = right(error),

View File

@ -36,28 +36,42 @@ class RowBloc extends Bloc<RowEvent, RowState> {
initial: (_InitialRow value) async {
_startListening();
await _loadRow(emit);
add(const RowEvent.didUpdateCell());
},
createRow: (_CreateRow value) {
rowService.createRow();
},
didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) {
emit(state.copyWith(fields: value.fields));
add(const RowEvent.didUpdateCell());
didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) async {
await _handleFieldUpdate(emit, value);
},
didUpdateCell: (_DidUpdateCell value) async {
final optionRow = await state.row;
final CellDataMap cellDataMap = optionRow.fold(
() => CellDataMap.identity(),
(row) => _makeCellDatas(row),
);
emit(state.copyWith(cellDataMap: Some(cellDataMap)));
didUpdateRow: (_DidUpdateRow value) async {
_handleRowUpdate(value, emit);
},
);
},
);
}
void _handleRowUpdate(_DidUpdateRow value, Emitter<RowState> emit) {
final CellDataMap cellDataMap = _makeCellDatas(value.row);
emit(state.copyWith(
row: Future(() => Some(value.row)),
cellDataMap: Some(cellDataMap),
));
}
Future<void> _handleFieldUpdate(Emitter<RowState> emit, _DidReceiveFieldUpdate value) async {
final optionRow = await state.row;
final CellDataMap cellDataMap = optionRow.fold(
() => CellDataMap.identity(),
(row) => _makeCellDatas(row),
);
emit(state.copyWith(
fields: value.fields,
cellDataMap: Some(cellDataMap),
));
}
@override
Future<void> close() async {
await rowlistener.stop();
@ -68,18 +82,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
Future<void> _startListening() async {
rowlistener.updateRowNotifier.addPublishListener((result) {
result.fold(
(row) {
//
},
(err) => Log.error(err),
);
});
rowlistener.updateCellNotifier.addPublishListener((result) {
result.fold(
(repeatedCell) {
Log.info("$repeatedCell");
},
(row) => add(RowEvent.didUpdateRow(row)),
(err) => Log.error(err),
);
});
@ -96,16 +99,12 @@ class RowBloc extends Bloc<RowEvent, RowState> {
}
Future<void> _loadRow(Emitter<RowState> emit) async {
final Future<Option<Row>> row = rowService.getRow().then((result) {
rowService.getRow().then((result) {
return result.fold(
(row) => Some(row),
(err) {
Log.error(err);
return none();
},
(row) => add(RowEvent.didUpdateRow(row)),
(err) => Log.error(err),
);
});
emit(state.copyWith(row: row));
}
CellDataMap _makeCellDatas(Row row) {
@ -130,7 +129,7 @@ class RowEvent with _$RowEvent {
const factory RowEvent.initial() = _InitialRow;
const factory RowEvent.createRow() = _CreateRow;
const factory RowEvent.didReceiveFieldUpdate(List<Field> fields) = _DidReceiveFieldUpdate;
const factory RowEvent.didUpdateCell() = _DidUpdateCell;
const factory RowEvent.didUpdateRow(Row row) = _DidUpdateRow;
}
@freezed

View File

@ -9,13 +9,11 @@ import 'dart:typed_data';
import 'package:app_flowy/core/notification_helper.dart';
import 'package:dartz/dartz.dart';
typedef UpdateCellNotifiedValue = Either<RepeatedCell, FlowyError>;
typedef UpdateRowNotifiedValue = Either<Row, FlowyError>;
typedef UpdateFieldNotifiedValue = Either<List<Field>, FlowyError>;
class RowListener {
final String rowId;
PublishNotifier<UpdateCellNotifiedValue> updateCellNotifier = PublishNotifier();
PublishNotifier<UpdateRowNotifiedValue> updateRowNotifier = PublishNotifier();
StreamSubscription<SubscribeObject>? _subscription;
GridNotificationParser? _parser;
@ -35,10 +33,10 @@ class RowListener {
void _handleObservableType(GridNotification ty, Either<Uint8List, FlowyError> result) {
switch (ty) {
case GridNotification.GridDidUpdateCells:
case GridNotification.DidUpdateRow:
result.fold(
(payload) => updateCellNotifier.value = left(RepeatedCell.fromBuffer(payload)),
(error) => updateCellNotifier.value = right(error),
(payload) => updateRowNotifier.value = left(Row.fromBuffer(payload)),
(error) => updateRowNotifier.value = right(error),
);
break;
default:
@ -49,7 +47,6 @@ class RowListener {
Future<void> stop() async {
_parser = null;
await _subscription?.cancel();
updateCellNotifier.dispose();
updateRowNotifier.dispose();
}
}

View File

@ -12,16 +12,16 @@ import 'package:protobuf/protobuf.dart' as $pb;
class GridNotification extends $pb.ProtobufEnum {
static const GridNotification Unknown = GridNotification._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown');
static const GridNotification DidCreateBlock = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidCreateBlock');
static const GridNotification DidUpdateRow = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateRow');
static const GridNotification GridDidUpdateCells = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateCells');
static const GridNotification DidUpdateBlock = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateBlock');
static const GridNotification DidUpdateRow = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateRow');
static const GridNotification DidUpdateFields = GridNotification._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateFields');
static const GridNotification DidUpdateField = GridNotification._(41, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DidUpdateField');
static const $core.List<GridNotification> values = <GridNotification> [
Unknown,
DidCreateBlock,
DidUpdateBlock,
DidUpdateRow,
GridDidUpdateCells,
DidUpdateFields,
DidUpdateField,
];

View File

@ -14,12 +14,12 @@ const GridNotification$json = const {
'2': const [
const {'1': 'Unknown', '2': 0},
const {'1': 'DidCreateBlock', '2': 11},
const {'1': 'DidUpdateRow', '2': 20},
const {'1': 'GridDidUpdateCells', '2': 30},
const {'1': 'DidUpdateBlock', '2': 20},
const {'1': 'DidUpdateRow', '2': 30},
const {'1': 'DidUpdateFields', '2': 40},
const {'1': 'DidUpdateField', '2': 41},
],
};
/// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhAKDERpZFVwZGF0ZVJvdxAUEhYKEkdyaWREaWRVcGRhdGVDZWxscxAeEhMKD0RpZFVwZGF0ZUZpZWxkcxAoEhIKDkRpZFVwZGF0ZUZpZWxkECk=');
final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABISCg5EaWRDcmVhdGVCbG9jaxALEhIKDkRpZFVwZGF0ZUJsb2NrEBQSEAoMRGlkVXBkYXRlUm93EB4SEwoPRGlkVXBkYXRlRmllbGRzECgSEgoORGlkVXBkYXRlRmllbGQQKQ==');

View File

@ -6,8 +6,8 @@ const OBSERVABLE_CATEGORY: &str = "Grid";
pub enum GridNotification {
Unknown = 0,
DidCreateBlock = 11,
DidUpdateRow = 20,
GridDidUpdateCells = 30,
DidUpdateBlock = 20,
DidUpdateRow = 30,
DidUpdateFields = 40,
DidUpdateField = 41,
}

View File

@ -27,8 +27,8 @@
pub enum GridNotification {
Unknown = 0,
DidCreateBlock = 11,
DidUpdateRow = 20,
GridDidUpdateCells = 30,
DidUpdateBlock = 20,
DidUpdateRow = 30,
DidUpdateFields = 40,
DidUpdateField = 41,
}
@ -42,8 +42,8 @@ impl ::protobuf::ProtobufEnum for GridNotification {
match value {
0 => ::std::option::Option::Some(GridNotification::Unknown),
11 => ::std::option::Option::Some(GridNotification::DidCreateBlock),
20 => ::std::option::Option::Some(GridNotification::DidUpdateRow),
30 => ::std::option::Option::Some(GridNotification::GridDidUpdateCells),
20 => ::std::option::Option::Some(GridNotification::DidUpdateBlock),
30 => ::std::option::Option::Some(GridNotification::DidUpdateRow),
40 => ::std::option::Option::Some(GridNotification::DidUpdateFields),
41 => ::std::option::Option::Some(GridNotification::DidUpdateField),
_ => ::std::option::Option::None
@ -54,8 +54,8 @@ impl ::protobuf::ProtobufEnum for GridNotification {
static values: &'static [GridNotification] = &[
GridNotification::Unknown,
GridNotification::DidCreateBlock,
GridNotification::DidUpdateBlock,
GridNotification::DidUpdateRow,
GridNotification::GridDidUpdateCells,
GridNotification::DidUpdateFields,
GridNotification::DidUpdateField,
];
@ -86,10 +86,10 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification {
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x17dart_notification.proto*\x86\x01\n\x10GridNotification\x12\x0b\n\
\x07Unknown\x10\0\x12\x12\n\x0eDidCreateBlock\x10\x0b\x12\x10\n\x0cDidUp\
dateRow\x10\x14\x12\x16\n\x12GridDidUpdateCells\x10\x1e\x12\x13\n\x0fDid\
UpdateFields\x10(\x12\x12\n\x0eDidUpdateField\x10)b\x06proto3\
\n\x17dart_notification.proto*\x82\x01\n\x10GridNotification\x12\x0b\n\
\x07Unknown\x10\0\x12\x12\n\x0eDidCreateBlock\x10\x0b\x12\x12\n\x0eDidUp\
dateBlock\x10\x14\x12\x10\n\x0cDidUpdateRow\x10\x1e\x12\x13\n\x0fDidUpda\
teFields\x10(\x12\x12\n\x0eDidUpdateField\x10)b\x06proto3\
";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -3,8 +3,8 @@ syntax = "proto3";
enum GridNotification {
Unknown = 0;
DidCreateBlock = 11;
DidUpdateRow = 20;
GridDidUpdateCells = 30;
DidUpdateBlock = 20;
DidUpdateRow = 30;
DidUpdateFields = 40;
DidUpdateField = 41;
}

View File

@ -1,12 +1,12 @@
use crate::dart_notification::{send_dart_notification, GridNotification};
use crate::manager::GridUser;
use crate::services::persistence::block_index::BlockIndexPersistence;
use crate::services::row::{make_block_row_ids, make_cell_by_field_id, GridBlockSnapshot};
use crate::services::row::{make_block_row_ids, make_cell_by_field_id, make_rows_from_row_metas, GridBlockSnapshot};
use bytes::Bytes;
use dashmap::DashMap;
use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::entities::{
CellMeta, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, GridBlockOrder, RepeatedCell, RowMeta,
CellMeta, FieldMeta, GridBlockMeta, GridBlockMetaChangeset, GridBlockOrder, RepeatedCell, Row, RowMeta,
RowMetaChangeset, RowOrder,
};
use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence;
@ -120,9 +120,10 @@ impl GridBlockMetaEditorManager {
}
pub async fn update_row_cells(&self, field_metas: &[FieldMeta], changeset: RowMetaChangeset) -> FlowyResult<()> {
let editor = self.get_editor_from_row_id(&changeset.row_id).await?;
let row_id = changeset.row_id.clone();
let editor = self.get_editor_from_row_id(&row_id).await?;
let _ = editor.update_row(changeset.clone()).await?;
self.notify_did_update_cells(changeset, field_metas)?;
self.notify_did_update_row(&row_id, field_metas).await?;
Ok(())
}
@ -171,35 +172,49 @@ impl GridBlockMetaEditorManager {
async fn notify_block_did_update_row(&self, block_id: &str) -> FlowyResult<()> {
let block_order: GridBlockOrder = block_id.into();
send_dart_notification(&self.grid_id, GridNotification::DidUpdateRow)
send_dart_notification(&self.grid_id, GridNotification::DidUpdateBlock)
.payload(block_order)
.send();
Ok(())
}
fn notify_did_update_cells(&self, changeset: RowMetaChangeset, field_metas: &[FieldMeta]) -> FlowyResult<()> {
let field_meta_map = field_metas
.iter()
.map(|field_meta| (&field_meta.id, field_meta))
.collect::<HashMap<&String, &FieldMeta>>();
let mut cells = vec![];
changeset
.cell_by_field_id
.into_iter()
.for_each(
|(field_id, cell_meta)| match make_cell_by_field_id(&field_meta_map, field_id, cell_meta) {
None => {}
Some((_, cell)) => cells.push(cell),
},
);
if !cells.is_empty() {
send_dart_notification(&changeset.row_id, GridNotification::GridDidUpdateCells)
.payload(RepeatedCell::from(cells))
.send();
async fn notify_did_update_row(&self, row_id: &str, field_metas: &[FieldMeta]) -> FlowyResult<()> {
match self.get_row_meta(row_id).await? {
None => {}
Some(row_meta) => {
let row_metas = vec![row_meta];
if let Some(row) = make_rows_from_row_metas(&field_metas, &row_metas).pop() {
send_dart_notification(row_id, GridNotification::DidUpdateRow)
.payload(row)
.send();
}
}
}
Ok(())
//
// let field_meta_map = field_metas
// .iter()
// .map(|field_meta| (&field_meta.id, field_meta))
// .collect::<HashMap<&String, &FieldMeta>>();
//
// let mut cells = vec![];
// changeset
// .cell_by_field_id
// .into_iter()
// .for_each(
// |(field_id, cell_meta)| match make_cell_by_field_id(&field_meta_map, field_id, cell_meta) {
// None => {}
// Some((_, cell)) => cells.push(cell),
// },
// );
//
// if !cells.is_empty() {
// send_dart_notification(&changeset.row_id, GridNotification::DidUpdateRow)
// .payload(RepeatedCell::from(cells))
// .send();
// }
// Ok(())
}
}