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) { void _handleObservableType(GridNotification ty, Either<Uint8List, FlowyError> result) {
switch (ty) { switch (ty) {
case GridNotification.DidUpdateRow: case GridNotification.DidUpdateBlock:
result.fold( result.fold(
(payload) => blockUpdateNotifier.value = left([GridBlockOrder.fromBuffer(payload)]), (payload) => blockUpdateNotifier.value = left([GridBlockOrder.fromBuffer(payload)]),
(error) => blockUpdateNotifier.value = right(error), (error) => blockUpdateNotifier.value = right(error),

View File

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

View File

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

View File

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

View File

@ -14,12 +14,12 @@ const GridNotification$json = const {
'2': const [ '2': const [
const {'1': 'Unknown', '2': 0}, const {'1': 'Unknown', '2': 0},
const {'1': 'DidCreateBlock', '2': 11}, const {'1': 'DidCreateBlock', '2': 11},
const {'1': 'DidUpdateRow', '2': 20}, const {'1': 'DidUpdateBlock', '2': 20},
const {'1': 'GridDidUpdateCells', '2': 30}, const {'1': 'DidUpdateRow', '2': 30},
const {'1': 'DidUpdateFields', '2': 40}, const {'1': 'DidUpdateFields', '2': 40},
const {'1': 'DidUpdateField', '2': 41}, const {'1': 'DidUpdateField', '2': 41},
], ],
}; };
/// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. /// 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 { pub enum GridNotification {
Unknown = 0, Unknown = 0,
DidCreateBlock = 11, DidCreateBlock = 11,
DidUpdateRow = 20, DidUpdateBlock = 20,
GridDidUpdateCells = 30, DidUpdateRow = 30,
DidUpdateFields = 40, DidUpdateFields = 40,
DidUpdateField = 41, DidUpdateField = 41,
} }

View File

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

View File

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