diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_listener.dart index 314345017e..05289fee03 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_listener.dart @@ -1,5 +1,4 @@ import 'package:dartz/dartz.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; import 'package:flowy_infra/notifier.dart'; @@ -7,16 +6,17 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:app_flowy/core/notification_helper.dart'; -typedef UpdateFieldNotifiedValue = Either; +typedef UpdateFieldNotifiedValue = Either; class CellListener { final String rowId; final String fieldId; - PublishNotifier? updateCellNotifier = PublishNotifier(); + PublishNotifier? _updateCellNotifier = PublishNotifier(); GridNotificationListener? _listener; CellListener({required this.rowId, required this.fieldId}); - void start() { + void start({required void Function(UpdateFieldNotifiedValue) onCellChanged}) { + _updateCellNotifier?.addPublishListener(onCellChanged); _listener = GridNotificationListener(objectId: "$rowId:$fieldId", handler: _handler); } @@ -24,8 +24,8 @@ class CellListener { switch (ty) { case GridNotification.DidUpdateCell: result.fold( - (payload) => updateCellNotifier?.value = left(CellNotificationData.fromBuffer(payload)), - (error) => updateCellNotifier?.value = right(error), + (payload) => _updateCellNotifier?.value = left(unit), + (error) => _updateCellNotifier?.value = right(error), ); break; default: @@ -35,7 +35,7 @@ class CellListener { Future stop() async { await _listener?.stop(); - updateCellNotifier?.dispose(); - updateCellNotifier = null; + _updateCellNotifier?.dispose(); + _updateCellNotifier = null; } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service.dart index f435a8ac9a..6c0128a848 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service.dart @@ -22,20 +22,18 @@ class GridCellContext { final GridCellCache cellCache; final GridCellCacheKey _cacheKey; final GridCellDataLoader cellDataLoader; - - final CellListener _cellListener; final CellService _cellService = CellService(); + + late final CellListener _cellListener; late final ValueNotifier _cellDataNotifier; + bool isListening = false; Timer? _delayOperation; GridCellContext({ required this.gridCell, required this.cellCache, required this.cellDataLoader, - }) : _cellListener = CellListener(rowId: gridCell.rowId, fieldId: gridCell.field.id), - _cacheKey = GridCellCacheKey(objectId: gridCell.rowId, fieldId: gridCell.field.id) { - _cellDataNotifier = ValueNotifier(cellCache.get(cacheKey)); - } + }) : _cacheKey = GridCellCacheKey(objectId: gridCell.rowId, fieldId: gridCell.field.id); String get gridId => gridCell.gridId; @@ -52,16 +50,20 @@ class GridCellContext { 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 (!isListening) { + isListening = true; + _cellDataNotifier = ValueNotifier(cellCache.get(cacheKey)); + _cellListener = CellListener(rowId: gridCell.rowId, fieldId: gridCell.field.id); + _cellListener.start(onCellChanged: (result) { + result.fold( + (_) => _loadData(), + (err) => Log.error(err), + ); + }); - if (cellDataLoader.reloadOnFieldChanged) { - cellCache.addListener(cacheKey, () => reloadCellData()); + if (cellDataLoader.reloadOnFieldChanged) { + cellCache.addListener(cacheKey, () => reloadCellData()); + } } _cellDataNotifier.addListener(() { @@ -171,7 +173,7 @@ class GridCellCache { final String gridId; final GridCellFieldDelegate fieldDelegate; - /// fieldId: {rowId: callback} + /// fieldId: {objectId: callback} final Map> _cellListenerByFieldId = {}; /// fieldId: {cacheKey: cacheData} diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart index 576e62e3b1..d0d2999b6c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart @@ -45,13 +45,15 @@ class FieldCellBloc extends Bloc { } void _startListening() { - _fieldListener.updateFieldNotifier?.addPublishListener((result) { + _fieldListener.start(onFieldChanged: (result) { + if (isClosed) { + return; + } result.fold( (field) => add(FieldCellEvent.didReceiveFieldUpdate(field)), (err) => Log.error(err), ); - }, listenWhen: () => !isClosed); - _fieldListener.start(); + }); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart index b31a9c3ff5..ec4ef77f30 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart @@ -11,12 +11,13 @@ typedef UpdateFieldNotifiedValue = Either; class SingleFieldListener { final String fieldId; - PublishNotifier? updateFieldNotifier = PublishNotifier(); + PublishNotifier? _updateFieldNotifier = PublishNotifier(); GridNotificationListener? _listener; SingleFieldListener({required this.fieldId}); - void start() { + void start({required void Function(UpdateFieldNotifiedValue) onFieldChanged}) { + _updateFieldNotifier?.addPublishListener(onFieldChanged); _listener = GridNotificationListener( objectId: fieldId, handler: _handler, @@ -30,8 +31,8 @@ class SingleFieldListener { switch (ty) { case GridNotification.DidUpdateField: result.fold( - (payload) => updateFieldNotifier?.value = left(Field.fromBuffer(payload)), - (error) => updateFieldNotifier?.value = right(error), + (payload) => _updateFieldNotifier?.value = left(Field.fromBuffer(payload)), + (error) => _updateFieldNotifier?.value = right(error), ); break; default: @@ -41,7 +42,7 @@ class SingleFieldListener { Future stop() async { await _listener?.stop(); - updateFieldNotifier?.dispose(); - updateFieldNotifier = null; + _updateFieldNotifier?.dispose(); + _updateFieldNotifier = null; } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart b/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart index 6774205a5e..e97d24a3e1 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart @@ -15,7 +15,8 @@ class GridFieldsListener { GridNotificationListener? _listener; GridFieldsListener({required this.gridId}); - void start() { + void start({required void Function(UpdateFieldNotifiedValue) onFieldsChanged}) { + updateFieldsNotifier?.addPublishListener(onFieldsChanged); _listener = GridNotificationListener( objectId: gridId, handler: _handler, diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index 4ea13499cb..7911b46eef 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -60,7 +60,7 @@ class GridFieldCache { final FieldsNotifier _fieldNotifier = FieldsNotifier(); GridFieldCache({required this.gridId}) { _fieldListener = GridFieldsListener(gridId: gridId); - _fieldListener.updateFieldsNotifier?.addPublishListener((result) { + _fieldListener.start(onFieldsChanged: (result) { result.fold( (changeset) { _deleteFields(changeset.deletedFields); @@ -70,7 +70,6 @@ class GridFieldCache { (err) => Log.error(err), ); }); - _fieldListener.start(); } Future dispose() async { diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index c904f1a2f9..82879b647e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -216,18 +216,18 @@ class RowsNotifier extends ChangeNotifier { _update(newRows, GridRowChangeReason.insert(insertIndexs)); } - void updateRows(List updatedRows) { + void updateRows(List updatedRows) { if (updatedRows.isEmpty) { return; } final UpdatedIndexs updatedIndexs = UpdatedIndexs(); final List newRows = clonedRows; - for (final rowOrder in updatedRows) { + for (final updatedRow in updatedRows) { + final rowOrder = updatedRow.rowOrder; final index = newRows.indexWhere((row) => row.rowId == rowOrder.rowId); if (index != -1) { - // Remove the old row data, the data will be filled if the loadRow method gets called. - _rowDataMap.remove(rowOrder.rowId); + _rowDataMap[rowOrder.rowId] = updatedRow.row; newRows.removeAt(index); newRows.insert(index, rowBuilder(rowOrder)); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index 44ab0813d1..adf088f5e4 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -3,7 +3,6 @@ import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart index e64431b1f9..30324be776 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart @@ -1081,12 +1081,77 @@ class IndexRowOrder extends $pb.GeneratedMessage { void clearIndex() => clearField(2); } +class UpdatedRowOrder extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UpdatedRowOrder', createEmptyInstance: create) + ..aOM(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrder', subBuilder: RowOrder.create) + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'row', subBuilder: Row.create) + ..hasRequiredFields = false + ; + + UpdatedRowOrder._() : super(); + factory UpdatedRowOrder({ + RowOrder? rowOrder, + Row? row, + }) { + final _result = create(); + if (rowOrder != null) { + _result.rowOrder = rowOrder; + } + if (row != null) { + _result.row = row; + } + return _result; + } + factory UpdatedRowOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory UpdatedRowOrder.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + UpdatedRowOrder clone() => UpdatedRowOrder()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + UpdatedRowOrder copyWith(void Function(UpdatedRowOrder) updates) => super.copyWith((message) => updates(message as UpdatedRowOrder)) as UpdatedRowOrder; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static UpdatedRowOrder create() => UpdatedRowOrder._(); + UpdatedRowOrder createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static UpdatedRowOrder getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static UpdatedRowOrder? _defaultInstance; + + @$pb.TagNumber(1) + RowOrder get rowOrder => $_getN(0); + @$pb.TagNumber(1) + set rowOrder(RowOrder v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasRowOrder() => $_has(0); + @$pb.TagNumber(1) + void clearRowOrder() => clearField(1); + @$pb.TagNumber(1) + RowOrder ensureRowOrder() => $_ensure(0); + + @$pb.TagNumber(2) + Row get row => $_getN(1); + @$pb.TagNumber(2) + set row(Row v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasRow() => $_has(1); + @$pb.TagNumber(2) + void clearRow() => clearField(2); + @$pb.TagNumber(2) + Row ensureRow() => $_ensure(1); +} + class GridRowsChangeset extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridRowsChangeset', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertedRows', $pb.PbFieldType.PM, subBuilder: IndexRowOrder.create) ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deletedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create) - ..pc(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'updatedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create) + ..pc(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'updatedRows', $pb.PbFieldType.PM, subBuilder: UpdatedRowOrder.create) ..hasRequiredFields = false ; @@ -1095,7 +1160,7 @@ class GridRowsChangeset extends $pb.GeneratedMessage { $core.String? blockId, $core.Iterable? insertedRows, $core.Iterable? deletedRows, - $core.Iterable? updatedRows, + $core.Iterable? updatedRows, }) { final _result = create(); if (blockId != null) { @@ -1149,7 +1214,7 @@ class GridRowsChangeset extends $pb.GeneratedMessage { $core.List get deletedRows => $_getList(2); @$pb.TagNumber(4) - $core.List get updatedRows => $_getList(3); + $core.List get updatedRows => $_getList(3); } class GridBlock extends $pb.GeneratedMessage { @@ -1268,108 +1333,6 @@ class Cell extends $pb.GeneratedMessage { void clearContent() => clearField(2); } -enum CellNotificationData_OneOfContent { - content, - notSet -} - -class CellNotificationData extends $pb.GeneratedMessage { - static const $core.Map<$core.int, CellNotificationData_OneOfContent> _CellNotificationData_OneOfContentByTag = { - 4 : CellNotificationData_OneOfContent.content, - 0 : CellNotificationData_OneOfContent.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellNotificationData', createEmptyInstance: create) - ..oo(0, [4]) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'content') - ..hasRequiredFields = false - ; - - CellNotificationData._() : super(); - factory CellNotificationData({ - $core.String? gridId, - $core.String? fieldId, - $core.String? rowId, - $core.String? content, - }) { - final _result = create(); - if (gridId != null) { - _result.gridId = gridId; - } - if (fieldId != null) { - _result.fieldId = fieldId; - } - if (rowId != null) { - _result.rowId = rowId; - } - if (content != null) { - _result.content = content; - } - return _result; - } - factory CellNotificationData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CellNotificationData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - CellNotificationData clone() => CellNotificationData()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CellNotificationData copyWith(void Function(CellNotificationData) updates) => super.copyWith((message) => updates(message as CellNotificationData)) as CellNotificationData; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CellNotificationData create() => CellNotificationData._(); - CellNotificationData createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static CellNotificationData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static CellNotificationData? _defaultInstance; - - CellNotificationData_OneOfContent whichOneOfContent() => _CellNotificationData_OneOfContentByTag[$_whichOneof(0)]!; - void clearOneOfContent() => clearField($_whichOneof(0)); - - @$pb.TagNumber(1) - $core.String get gridId => $_getSZ(0); - @$pb.TagNumber(1) - set gridId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasGridId() => $_has(0); - @$pb.TagNumber(1) - void clearGridId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get fieldId => $_getSZ(1); - @$pb.TagNumber(2) - set fieldId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasFieldId() => $_has(1); - @$pb.TagNumber(2) - void clearFieldId() => clearField(2); - - @$pb.TagNumber(3) - $core.String get rowId => $_getSZ(2); - @$pb.TagNumber(3) - set rowId($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasRowId() => $_has(2); - @$pb.TagNumber(3) - void clearRowId() => clearField(3); - - @$pb.TagNumber(4) - $core.String get content => $_getSZ(3); - @$pb.TagNumber(4) - set content($core.String v) { $_setString(3, v); } - @$pb.TagNumber(4) - $core.bool hasContent() => $_has(3); - @$pb.TagNumber(4) - void clearContent() => clearField(4); -} - class RepeatedCell extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedCell', createEmptyInstance: create) ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Cell.create) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index 722a8ebcd6..8ec90dddf9 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -236,6 +236,17 @@ const IndexRowOrder$json = const { /// Descriptor for `IndexRowOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List indexRowOrderDescriptor = $convert.base64Decode('Cg1JbmRleFJvd09yZGVyEiYKCXJvd19vcmRlchgBIAEoCzIJLlJvd09yZGVyUghyb3dPcmRlchIWCgVpbmRleBgCIAEoBUgAUgVpbmRleEIOCgxvbmVfb2ZfaW5kZXg='); +@$core.Deprecated('Use updatedRowOrderDescriptor instead') +const UpdatedRowOrder$json = const { + '1': 'UpdatedRowOrder', + '2': const [ + const {'1': 'row_order', '3': 1, '4': 1, '5': 11, '6': '.RowOrder', '10': 'rowOrder'}, + const {'1': 'row', '3': 2, '4': 1, '5': 11, '6': '.Row', '10': 'row'}, + ], +}; + +/// Descriptor for `UpdatedRowOrder`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List updatedRowOrderDescriptor = $convert.base64Decode('Cg9VcGRhdGVkUm93T3JkZXISJgoJcm93X29yZGVyGAEgASgLMgkuUm93T3JkZXJSCHJvd09yZGVyEhYKA3JvdxgCIAEoCzIELlJvd1IDcm93'); @$core.Deprecated('Use gridRowsChangesetDescriptor instead') const GridRowsChangeset$json = const { '1': 'GridRowsChangeset', @@ -243,12 +254,12 @@ const GridRowsChangeset$json = const { const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, const {'1': 'inserted_rows', '3': 2, '4': 3, '5': 11, '6': '.IndexRowOrder', '10': 'insertedRows'}, const {'1': 'deleted_rows', '3': 3, '4': 3, '5': 11, '6': '.RowOrder', '10': 'deletedRows'}, - const {'1': 'updated_rows', '3': 4, '4': 3, '5': 11, '6': '.RowOrder', '10': 'updatedRows'}, + const {'1': 'updated_rows', '3': 4, '4': 3, '5': 11, '6': '.UpdatedRowOrder', '10': 'updatedRows'}, ], }; /// Descriptor for `GridRowsChangeset`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridRowsChangesetDescriptor = $convert.base64Decode('ChFHcmlkUm93c0NoYW5nZXNldBIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIzCg1pbnNlcnRlZF9yb3dzGAIgAygLMg4uSW5kZXhSb3dPcmRlclIMaW5zZXJ0ZWRSb3dzEiwKDGRlbGV0ZWRfcm93cxgDIAMoCzIJLlJvd09yZGVyUgtkZWxldGVkUm93cxIsCgx1cGRhdGVkX3Jvd3MYBCADKAsyCS5Sb3dPcmRlclILdXBkYXRlZFJvd3M='); +final $typed_data.Uint8List gridRowsChangesetDescriptor = $convert.base64Decode('ChFHcmlkUm93c0NoYW5nZXNldBIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIzCg1pbnNlcnRlZF9yb3dzGAIgAygLMg4uSW5kZXhSb3dPcmRlclIMaW5zZXJ0ZWRSb3dzEiwKDGRlbGV0ZWRfcm93cxgDIAMoCzIJLlJvd09yZGVyUgtkZWxldGVkUm93cxIzCgx1cGRhdGVkX3Jvd3MYBCADKAsyEC5VcGRhdGVkUm93T3JkZXJSC3VwZGF0ZWRSb3dz'); @$core.Deprecated('Use gridBlockDescriptor instead') const GridBlock$json = const { '1': 'GridBlock', @@ -271,22 +282,6 @@ const Cell$json = const { /// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhgKB2NvbnRlbnQYAiABKAlSB2NvbnRlbnQ='); -@$core.Deprecated('Use cellNotificationDataDescriptor instead') -const CellNotificationData$json = const { - '1': 'CellNotificationData', - '2': const [ - const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'row_id', '3': 3, '4': 1, '5': 9, '10': 'rowId'}, - const {'1': 'content', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'content'}, - ], - '8': const [ - const {'1': 'one_of_content'}, - ], -}; - -/// Descriptor for `CellNotificationData`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellNotificationDataDescriptor = $convert.base64Decode('ChRDZWxsTm90aWZpY2F0aW9uRGF0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSGQoIZmllbGRfaWQYAiABKAlSB2ZpZWxkSWQSFQoGcm93X2lkGAMgASgJUgVyb3dJZBIaCgdjb250ZW50GAQgASgJSABSB2NvbnRlbnRCEAoOb25lX29mX2NvbnRlbnQ='); @$core.Deprecated('Use repeatedCellDescriptor instead') const RepeatedCell$json = const { '1': 'RepeatedCell', diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs index cdc06d8723..7853d99c18 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs @@ -6,13 +6,14 @@ use crate::services::row::{group_row_orders, GridBlockSnapshot}; use std::borrow::Cow; use dashmap::DashMap; -use flowy_error::FlowyResult; +use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - CellChangeset, CellMeta, CellNotificationData, GridBlockMeta, GridBlockMetaChangeset, GridRowsChangeset, - IndexRowOrder, RowMeta, RowMetaChangeset, RowOrder, + Cell, CellChangeset, CellMeta, GridBlockMeta, GridBlockMetaChangeset, GridRowsChangeset, IndexRowOrder, Row, + RowMeta, RowMetaChangeset, RowOrder, UpdatedRowOrder, }; use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_revision::{RevisionManager, RevisionPersistence}; +use lib_infra::future::FutureResult; use std::collections::HashMap; use std::sync::Arc; @@ -108,10 +109,22 @@ impl GridBlockMetaEditorManager { Ok(changesets) } - pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { + pub async fn update_row(&self, changeset: RowMetaChangeset, row_builder: F) -> FlowyResult<()> + where + F: FnOnce(Arc) -> Option, + { let editor = self.get_editor_from_row_id(&changeset.row_id).await?; let _ = editor.update_row(changeset.clone()).await?; - let _ = self.notify_did_update_block_row(&changeset.row_id).await?; + match editor.get_row_meta(&changeset.row_id).await? { + None => tracing::error!("Internal error: can't find the row with id: {}", changeset.row_id), + Some(row_meta) => { + if let Some(row) = row_builder(row_meta.clone()) { + let row_order = UpdatedRowOrder::new(&row_meta, row); + let block_order_changeset = GridRowsChangeset::update(&editor.block_id, vec![row_order]); + let _ = self.notify_did_update_block(block_order_changeset).await?; + } + } + } Ok(()) } @@ -175,18 +188,13 @@ impl GridBlockMetaEditorManager { Ok(()) } - pub async fn update_cell(&self, changeset: CellChangeset) -> FlowyResult<()> { + pub async fn update_cell(&self, changeset: CellChangeset, row_builder: F) -> FlowyResult<()> + where + F: FnOnce(Arc) -> Option, + { let row_changeset: RowMetaChangeset = changeset.clone().into(); - let _ = self.update_row(row_changeset).await?; - - let cell_notification_data = CellNotificationData { - grid_id: changeset.grid_id, - field_id: changeset.field_id, - row_id: changeset.row_id, - content: changeset.data, - }; - self.notify_did_update_cell(cell_notification_data).await?; - + let _ = self.update_row(row_changeset, row_builder).await?; + self.notify_did_update_cell(changeset).await?; Ok(()) } @@ -233,19 +241,6 @@ impl GridBlockMetaEditorManager { Ok(block_cell_metas) } - async fn notify_did_update_block_row(&self, row_id: &str) -> FlowyResult<()> { - let editor = self.get_editor_from_row_id(row_id).await?; - match editor.get_row_order(row_id).await? { - None => {} - Some(row_order) => { - let block_order_changeset = GridRowsChangeset::update(&editor.block_id, vec![row_order]); - let _ = self.notify_did_update_block(block_order_changeset).await?; - } - } - - Ok(()) - } - async fn notify_did_update_block(&self, changeset: GridRowsChangeset) -> FlowyResult<()> { send_dart_notification(&self.grid_id, GridNotification::DidUpdateGridRow) .payload(changeset) @@ -253,11 +248,9 @@ impl GridBlockMetaEditorManager { Ok(()) } - async fn notify_did_update_cell(&self, data: CellNotificationData) -> FlowyResult<()> { - let id = format!("{}:{}", data.row_id, data.field_id); - send_dart_notification(&id, GridNotification::DidUpdateCell) - .payload(data) - .send(); + async fn notify_did_update_cell(&self, changeset: CellChangeset) -> FlowyResult<()> { + let id = format!("{}:{}", changeset.row_id, changeset.field_id); + send_dart_notification(&id, GridNotification::DidUpdateCell).send(); Ok(()) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 8f30c0a7cd..05437f46cd 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -247,7 +247,10 @@ impl ClientGridEditor { } pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { - self.block_meta_manager.update_row(changeset).await + let field_metas = self.get_field_metas::(None).await?; + self.block_meta_manager + .update_row(changeset, |row_meta| make_row_from_row_meta(&field_metas, row_meta)) + .await } pub async fn get_rows(&self, block_id: &str) -> FlowyResult { @@ -322,7 +325,11 @@ impl ClientGridEditor { Some((_, field_meta)) => { // Update the changeset.data property with the return value. changeset.data = Some(apply_cell_data_changeset(cell_data_changeset, cell_meta, field_meta)?); - let _ = self.block_meta_manager.update_cell(changeset).await?; + let field_metas = self.get_field_metas::(None).await?; + let _ = self + .block_meta_manager + .update_cell(changeset, |row_meta| make_row_from_row_meta(&field_metas, row_meta)) + .await?; Ok(()) } } @@ -423,6 +430,11 @@ impl ClientGridEditor { self.grid_pad.read().await.delta_bytes() } + async fn row_builder(&self, row_meta: Arc) -> FlowyResult> { + let field_metas = self.get_field_metas::(None).await?; + Ok(make_rows_from_row_metas(&field_metas, &[row_meta]).pop()) + } + async fn modify(&self, f: F) -> FlowyResult<()> where F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult>, diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index 770ba758e9..35357a0c83 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -47,6 +47,10 @@ pub(crate) fn make_row_orders_from_row_metas(row_metas: &[Arc]) -> Vec< row_metas.iter().map(RowOrder::from).collect::>() } +pub(crate) fn make_row_from_row_meta(fields: &[FieldMeta], row_meta: Arc) -> Option { + make_rows_from_row_metas(fields, &vec![row_meta]).pop() +} + pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &[Arc]) -> Vec { let field_meta_map = fields .iter() diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index d246fd490b..c2f6d3841b 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -352,7 +352,25 @@ pub struct IndexRowOrder { pub index: Option, } -#[derive(Debug, Clone, Default, ProtoBuf)] +#[derive(Debug, Default, ProtoBuf)] +pub struct UpdatedRowOrder { + #[pb(index = 1)] + pub row_order: RowOrder, + + #[pb(index = 2)] + pub row: Row, +} + +impl UpdatedRowOrder { + pub fn new(row_meta: &RowMeta, row: Row) -> Self { + Self { + row_order: RowOrder::from(row_meta), + row, + } + } +} + +#[derive(Debug, Default, ProtoBuf)] pub struct GridRowsChangeset { #[pb(index = 1)] pub block_id: String, @@ -364,7 +382,7 @@ pub struct GridRowsChangeset { pub deleted_rows: Vec, #[pb(index = 4)] - pub updated_rows: Vec, + pub updated_rows: Vec, } impl std::convert::From for IndexRowOrder { @@ -399,7 +417,7 @@ impl GridRowsChangeset { } } - pub fn update(block_id: &str, updated_rows: Vec) -> Self { + pub fn update(block_id: &str, updated_rows: Vec) -> Self { Self { block_id: block_id.to_owned(), inserted_rows: vec![], @@ -445,21 +463,6 @@ impl Cell { } } -#[derive(Debug, Clone, Default, ProtoBuf)] -pub struct CellNotificationData { - #[pb(index = 1)] - pub grid_id: String, - - #[pb(index = 2)] - pub field_id: String, - - #[pb(index = 3)] - pub row_id: String, - - #[pb(index = 4, one_of)] - pub content: Option, -} - #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedCell { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index 754fc11386..ccf489b8fd 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs @@ -3701,13 +3701,244 @@ impl ::protobuf::reflect::ProtobufValue for IndexRowOrder { } } +#[derive(PartialEq,Clone,Default)] +pub struct UpdatedRowOrder { + // message fields + pub row_order: ::protobuf::SingularPtrField, + pub row: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a UpdatedRowOrder { + fn default() -> &'a UpdatedRowOrder { + ::default_instance() + } +} + +impl UpdatedRowOrder { + pub fn new() -> UpdatedRowOrder { + ::std::default::Default::default() + } + + // .RowOrder row_order = 1; + + + pub fn get_row_order(&self) -> &RowOrder { + self.row_order.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_row_order(&mut self) { + self.row_order.clear(); + } + + pub fn has_row_order(&self) -> bool { + self.row_order.is_some() + } + + // Param is passed by value, moved + pub fn set_row_order(&mut self, v: RowOrder) { + self.row_order = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_order(&mut self) -> &mut RowOrder { + if self.row_order.is_none() { + self.row_order.set_default(); + } + self.row_order.as_mut().unwrap() + } + + // Take field + pub fn take_row_order(&mut self) -> RowOrder { + self.row_order.take().unwrap_or_else(|| RowOrder::new()) + } + + // .Row row = 2; + + + pub fn get_row(&self) -> &Row { + self.row.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_row(&mut self) { + self.row.clear(); + } + + pub fn has_row(&self) -> bool { + self.row.is_some() + } + + // Param is passed by value, moved + pub fn set_row(&mut self, v: Row) { + self.row = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row(&mut self) -> &mut Row { + if self.row.is_none() { + self.row.set_default(); + } + self.row.as_mut().unwrap() + } + + // Take field + pub fn take_row(&mut self) -> Row { + self.row.take().unwrap_or_else(|| Row::new()) + } +} + +impl ::protobuf::Message for UpdatedRowOrder { + fn is_initialized(&self) -> bool { + for v in &self.row_order { + if !v.is_initialized() { + return false; + } + }; + for v in &self.row { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.row_order)?; + }, + 2 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.row)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(ref v) = self.row_order.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if let Some(ref v) = self.row.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if let Some(ref v) = self.row_order.as_ref() { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if let Some(ref v) = self.row.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> UpdatedRowOrder { + UpdatedRowOrder::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "row_order", + |m: &UpdatedRowOrder| { &m.row_order }, + |m: &mut UpdatedRowOrder| { &mut m.row_order }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "row", + |m: &UpdatedRowOrder| { &m.row }, + |m: &mut UpdatedRowOrder| { &mut m.row }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "UpdatedRowOrder", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static UpdatedRowOrder { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(UpdatedRowOrder::new) + } +} + +impl ::protobuf::Clear for UpdatedRowOrder { + fn clear(&mut self) { + self.row_order.clear(); + self.row.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for UpdatedRowOrder { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for UpdatedRowOrder { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct GridRowsChangeset { // message fields pub block_id: ::std::string::String, pub inserted_rows: ::protobuf::RepeatedField, pub deleted_rows: ::protobuf::RepeatedField, - pub updated_rows: ::protobuf::RepeatedField, + pub updated_rows: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -3800,10 +4031,10 @@ impl GridRowsChangeset { ::std::mem::replace(&mut self.deleted_rows, ::protobuf::RepeatedField::new()) } - // repeated .RowOrder updated_rows = 4; + // repeated .UpdatedRowOrder updated_rows = 4; - pub fn get_updated_rows(&self) -> &[RowOrder] { + pub fn get_updated_rows(&self) -> &[UpdatedRowOrder] { &self.updated_rows } pub fn clear_updated_rows(&mut self) { @@ -3811,17 +4042,17 @@ impl GridRowsChangeset { } // Param is passed by value, moved - pub fn set_updated_rows(&mut self, v: ::protobuf::RepeatedField) { + pub fn set_updated_rows(&mut self, v: ::protobuf::RepeatedField) { self.updated_rows = v; } // Mutable pointer to the field. - pub fn mut_updated_rows(&mut self) -> &mut ::protobuf::RepeatedField { + pub fn mut_updated_rows(&mut self) -> &mut ::protobuf::RepeatedField { &mut self.updated_rows } // Take field - pub fn take_updated_rows(&mut self) -> ::protobuf::RepeatedField { + pub fn take_updated_rows(&mut self) -> ::protobuf::RepeatedField { ::std::mem::replace(&mut self.updated_rows, ::protobuf::RepeatedField::new()) } } @@ -3966,7 +4197,7 @@ impl ::protobuf::Message for GridRowsChangeset { |m: &GridRowsChangeset| { &m.deleted_rows }, |m: &mut GridRowsChangeset| { &mut m.deleted_rows }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "updated_rows", |m: &GridRowsChangeset| { &m.updated_rows }, |m: &mut GridRowsChangeset| { &mut m.updated_rows }, @@ -4416,331 +4647,6 @@ impl ::protobuf::reflect::ProtobufValue for Cell { } } -#[derive(PartialEq,Clone,Default)] -pub struct CellNotificationData { - // message fields - pub grid_id: ::std::string::String, - pub field_id: ::std::string::String, - pub row_id: ::std::string::String, - // message oneof groups - pub one_of_content: ::std::option::Option, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a CellNotificationData { - fn default() -> &'a CellNotificationData { - ::default_instance() - } -} - -#[derive(Clone,PartialEq,Debug)] -pub enum CellNotificationData_oneof_one_of_content { - content(::std::string::String), -} - -impl CellNotificationData { - pub fn new() -> CellNotificationData { - ::std::default::Default::default() - } - - // string grid_id = 1; - - - pub fn get_grid_id(&self) -> &str { - &self.grid_id - } - pub fn clear_grid_id(&mut self) { - self.grid_id.clear(); - } - - // Param is passed by value, moved - pub fn set_grid_id(&mut self, v: ::std::string::String) { - self.grid_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { - &mut self.grid_id - } - - // Take field - pub fn take_grid_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) - } - - // string field_id = 2; - - - pub fn get_field_id(&self) -> &str { - &self.field_id - } - pub fn clear_field_id(&mut self) { - self.field_id.clear(); - } - - // Param is passed by value, moved - pub fn set_field_id(&mut self, v: ::std::string::String) { - self.field_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_field_id(&mut self) -> &mut ::std::string::String { - &mut self.field_id - } - - // Take field - pub fn take_field_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) - } - - // string row_id = 3; - - - pub fn get_row_id(&self) -> &str { - &self.row_id - } - pub fn clear_row_id(&mut self) { - self.row_id.clear(); - } - - // Param is passed by value, moved - pub fn set_row_id(&mut self, v: ::std::string::String) { - self.row_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_row_id(&mut self) -> &mut ::std::string::String { - &mut self.row_id - } - - // Take field - pub fn take_row_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) - } - - // string content = 4; - - - pub fn get_content(&self) -> &str { - match self.one_of_content { - ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(ref v)) => v, - _ => "", - } - } - pub fn clear_content(&mut self) { - self.one_of_content = ::std::option::Option::None; - } - - pub fn has_content(&self) -> bool { - match self.one_of_content { - ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_content(&mut self, v: ::std::string::String) { - self.one_of_content = ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(v)) - } - - // Mutable pointer to the field. - pub fn mut_content(&mut self) -> &mut ::std::string::String { - if let ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(_)) = self.one_of_content { - } else { - self.one_of_content = ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(::std::string::String::new())); - } - match self.one_of_content { - ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_content(&mut self) -> ::std::string::String { - if self.has_content() { - match self.one_of_content.take() { - ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(v)) => v, - _ => panic!(), - } - } else { - ::std::string::String::new() - } - } -} - -impl ::protobuf::Message for CellNotificationData { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; - }, - 4 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.one_of_content = ::std::option::Option::Some(CellNotificationData_oneof_one_of_content::content(is.read_string()?)); - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.grid_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.grid_id); - } - if !self.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.field_id); - } - if !self.row_id.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.row_id); - } - if let ::std::option::Option::Some(ref v) = self.one_of_content { - match v { - &CellNotificationData_oneof_one_of_content::content(ref v) => { - my_size += ::protobuf::rt::string_size(4, &v); - }, - }; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.grid_id.is_empty() { - os.write_string(1, &self.grid_id)?; - } - if !self.field_id.is_empty() { - os.write_string(2, &self.field_id)?; - } - if !self.row_id.is_empty() { - os.write_string(3, &self.row_id)?; - } - if let ::std::option::Option::Some(ref v) = self.one_of_content { - match v { - &CellNotificationData_oneof_one_of_content::content(ref v) => { - os.write_string(4, v)?; - }, - }; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> CellNotificationData { - CellNotificationData::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "grid_id", - |m: &CellNotificationData| { &m.grid_id }, - |m: &mut CellNotificationData| { &mut m.grid_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "field_id", - |m: &CellNotificationData| { &m.field_id }, - |m: &mut CellNotificationData| { &mut m.field_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_id", - |m: &CellNotificationData| { &m.row_id }, - |m: &mut CellNotificationData| { &mut m.row_id }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( - "content", - CellNotificationData::has_content, - CellNotificationData::get_content, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "CellNotificationData", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static CellNotificationData { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(CellNotificationData::new) - } -} - -impl ::protobuf::Clear for CellNotificationData { - fn clear(&mut self) { - self.grid_id.clear(); - self.field_id.clear(); - self.row_id.clear(); - self.one_of_content = ::std::option::Option::None; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for CellNotificationData { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for CellNotificationData { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct RepeatedCell { // message fields @@ -7843,56 +7749,54 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_orders\x18\ \x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\"_\n\rIndexRowOrder\x12&\n\tro\ w_order\x18\x01\x20\x01(\x0b2\t.RowOrderR\x08rowOrder\x12\x16\n\x05index\ - \x18\x02\x20\x01(\x05H\0R\x05indexB\x0e\n\x0cone_of_index\"\xbf\x01\n\ - \x11GridRowsChangeset\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07block\ - Id\x123\n\rinserted_rows\x18\x02\x20\x03(\x0b2\x0e.IndexRowOrderR\x0cins\ - ertedRows\x12,\n\x0cdeleted_rows\x18\x03\x20\x03(\x0b2\t.RowOrderR\x0bde\ - letedRows\x12,\n\x0cupdated_rows\x18\x04\x20\x03(\x0b2\t.RowOrderR\x0bup\ - datedRows\"E\n\tGridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\ - \n\nrow_orders\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\ - \x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07conte\ - nt\x18\x02\x20\x01(\tR\x07content\"\x8f\x01\n\x14CellNotificationData\ - \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_i\ - d\x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\ - \x05rowId\x12\x1a\n\x07content\x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\ - \x0eone_of_content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\ - \x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04nam\ - e\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\ - \x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\ - \x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\ - \x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0\ - R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12InsertFieldPa\ - yload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05fi\ - eld\x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\ - \x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\ - \x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\ - \x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ - \x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\ - \x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\ - \x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\ - \x0f.GridBlockOrderR\x0bblockOrders\"\xa8\x03\n\x15FieldChangesetPayload\ - \x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_\ - id\x18\x02\x20\x01(\tR\x06gridId\x12\x14\n\x04name\x18\x03\x20\x01(\tH\0\ - R\x04name\x12\x14\n\x04desc\x18\x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfie\ - ld_type\x18\x05\x20\x01(\x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\x06\ - frozen\x18\x06\x20\x01(\x08H\x03R\x06frozen\x12\x20\n\nvisibility\x18\ - \x07\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\x18\x08\x20\x01(\ - \x05H\x05R\x05width\x12*\n\x10type_option_data\x18\t\x20\x01(\x0cH\x06R\ - \x0etypeOptionDataB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x13\n\x11one\ - _of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_of_visibilityB\x0e\n\ - \x0cone_of_widthB\x19\n\x17one_of_type_option_data\"\x9c\x01\n\x0fMoveIt\ - emPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x17\n\ - \x07item_id\x18\x02\x20\x01(\tR\x06itemId\x12\x1d\n\nfrom_index\x18\x03\ - \x20\x01(\x05R\tfromIndex\x12\x19\n\x08to_index\x18\x04\x20\x01(\x05R\ - \x07toIndex\x12\x1d\n\x02ty\x18\x05\x20\x01(\x0e2\r.MoveItemTypeR\x02ty\ - \"\x7f\n\rCellChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06grid\ - Id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_i\ - d\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0\ - R\x04dataB\r\n\x0bone_of_data**\n\x0cMoveItemType\x12\r\n\tMoveField\x10\ - \0\x12\x0b\n\x07MoveRow\x10\x01*d\n\tFieldType\x12\x0c\n\x08RichText\x10\ - \0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0c\ - SingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Check\ - box\x10\x05b\x06proto3\ + \x18\x02\x20\x01(\x05H\0R\x05indexB\x0e\n\x0cone_of_index\"Q\n\x0fUpdate\ + dRowOrder\x12&\n\trow_order\x18\x01\x20\x01(\x0b2\t.RowOrderR\x08rowOrde\ + r\x12\x16\n\x03row\x18\x02\x20\x01(\x0b2\x04.RowR\x03row\"\xc6\x01\n\x11\ + GridRowsChangeset\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\ + \x123\n\rinserted_rows\x18\x02\x20\x03(\x0b2\x0e.IndexRowOrderR\x0cinser\ + tedRows\x12,\n\x0cdeleted_rows\x18\x03\x20\x03(\x0b2\t.RowOrderR\x0bdele\ + tedRows\x123\n\x0cupdated_rows\x18\x04\x20\x03(\x0b2\x10.UpdatedRowOrder\ + R\x0bupdatedRows\"E\n\tGridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02\ + id\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\ + \x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\ + \x07content\x18\x02\x20\x01(\tR\x07content\"+\n\x0cRepeatedCell\x12\x1b\ + \n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridP\ + ayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\ + \x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\ + \x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\ + \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row\ + _id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\ + \xb6\x01\n\x12InsertFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\t\ + R\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\ + \x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\ + \n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15on\ + e_of_start_field_id\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\ + \x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\ + \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orde\ + rs\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblockOrders\"\xa8\x03\n\ + \x15FieldChangesetPayload\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07f\ + ieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\x12\x14\n\x04n\ + ame\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x04\x20\x01(\tH\ + \x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\x0e2\n.FieldTypeH\x02R\ + \tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\x08H\x03R\x06frozen\x12\ + \x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05w\ + idth\x18\x08\x20\x01(\x05H\x05R\x05width\x12*\n\x10type_option_data\x18\ + \t\x20\x01(\x0cH\x06R\x0etypeOptionDataB\r\n\x0bone_of_nameB\r\n\x0bone_\ + of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_\ + of_visibilityB\x0e\n\x0cone_of_widthB\x19\n\x17one_of_type_option_data\"\ + \x9c\x01\n\x0fMoveItemPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \x06gridId\x12\x17\n\x07item_id\x18\x02\x20\x01(\tR\x06itemId\x12\x1d\n\ + \nfrom_index\x18\x03\x20\x01(\x05R\tfromIndex\x12\x19\n\x08to_index\x18\ + \x04\x20\x01(\x05R\x07toIndex\x12\x1d\n\x02ty\x18\x05\x20\x01(\x0e2\r.Mo\ + veItemTypeR\x02ty\"\x7f\n\rCellChangeset\x12\x17\n\x07grid_id\x18\x01\ + \x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\ + \x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\ + \x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data**\n\x0cMoveItemType\ + \x12\r\n\tMoveField\x10\0\x12\x0b\n\x07MoveRow\x10\x01*d\n\tFieldType\ + \x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08Date\ + Time\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\ + \x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 2d6dbecfe4..5d72f77302 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto @@ -73,11 +73,15 @@ message IndexRowOrder { RowOrder row_order = 1; oneof one_of_index { int32 index = 2; }; } +message UpdatedRowOrder { + RowOrder row_order = 1; + Row row = 2; +} message GridRowsChangeset { string block_id = 1; repeated IndexRowOrder inserted_rows = 2; repeated RowOrder deleted_rows = 3; - repeated RowOrder updated_rows = 4; + repeated UpdatedRowOrder updated_rows = 4; } message GridBlock { string id = 1; @@ -87,12 +91,6 @@ message Cell { string field_id = 1; string content = 2; } -message CellNotificationData { - string grid_id = 1; - string field_id = 2; - string row_id = 3; - oneof one_of_content { string content = 4; }; -} message RepeatedCell { repeated Cell items = 1; }