diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index 7c82e17ba7..c46687a2df 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -7,6 +7,7 @@ extend = [ { path = "scripts/makefile/docker.toml" }, { path = "scripts/makefile/env.toml" }, { path = "scripts/makefile/flutter.toml" }, + { path = "scripts/makefile/tool.toml" }, ] [config] diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart index 23b68f2f87..dea8e87712 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart @@ -15,7 +15,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart'; import 'package:app_flowy/workspace/application/grid/cell/select_option_service.dart'; import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; - +import 'dart:convert' show utf8; part 'cell_service.freezed.dart'; part 'data_loader.dart'; part 'context_builder.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/context_builder.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/context_builder.dart index 8680c7db76..709df1cb97 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/context_builder.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/context_builder.dart @@ -1,6 +1,6 @@ part of 'cell_service.dart'; -typedef GridCellContext = _GridCellContext; +typedef GridCellContext = _GridCellContext; typedef GridSelectOptionCellContext = _GridCellContext; typedef GridDateCellContext = _GridCellContext; typedef GridURLCellContext = _GridCellContext; @@ -17,26 +17,33 @@ class GridCellContextBuilder { _GridCellContext build() { switch (_gridCell.field.fieldType) { case FieldType.Checkbox: + final cellDataLoader = GridCellDataLoader( + gridCell: _gridCell, + parser: StringCellDataParser(), + ); return GridCellContext( gridCell: _gridCell, cellCache: _cellCache, - cellDataLoader: GridCellDataLoader(gridCell: _gridCell), + cellDataLoader: cellDataLoader, cellDataPersistence: CellDataPersistence(gridCell: _gridCell), ); case FieldType.DateTime: + final cellDataLoader = GridCellDataLoader( + gridCell: _gridCell, + parser: DateCellDataParser(), + ); + return GridDateCellContext( gridCell: _gridCell, cellCache: _cellCache, - cellDataLoader: DateCellDataLoader(gridCell: _gridCell), + cellDataLoader: cellDataLoader, cellDataPersistence: DateCellDataPersistence(gridCell: _gridCell), ); case FieldType.Number: final cellDataLoader = GridCellDataLoader( gridCell: _gridCell, - config: const GridCellDataConfig( - reloadOnCellChanged: true, - reloadOnFieldChanged: true, - ), + parser: StringCellDataParser(), + config: const GridCellDataConfig(reloadOnCellChanged: true, reloadOnFieldChanged: true), ); return GridCellContext( gridCell: _gridCell, @@ -45,26 +52,40 @@ class GridCellContextBuilder { cellDataPersistence: CellDataPersistence(gridCell: _gridCell), ); case FieldType.RichText: + final cellDataLoader = GridCellDataLoader( + gridCell: _gridCell, + parser: StringCellDataParser(), + ); return GridCellContext( gridCell: _gridCell, cellCache: _cellCache, - cellDataLoader: GridCellDataLoader(gridCell: _gridCell), + cellDataLoader: cellDataLoader, cellDataPersistence: CellDataPersistence(gridCell: _gridCell), ); case FieldType.MultiSelect: case FieldType.SingleSelect: + final cellDataLoader = GridCellDataLoader( + gridCell: _gridCell, + parser: SelectOptionCellDataParser(), + config: const GridCellDataConfig(reloadOnFieldChanged: true), + ); + return GridSelectOptionCellContext( gridCell: _gridCell, cellCache: _cellCache, - cellDataLoader: SelectOptionCellDataLoader(gridCell: _gridCell), + cellDataLoader: cellDataLoader, cellDataPersistence: CellDataPersistence(gridCell: _gridCell), ); case FieldType.URL: + final cellDataLoader = GridCellDataLoader( + gridCell: _gridCell, + parser: URLCellDataParser(), + ); return GridURLCellContext( gridCell: _gridCell, cellCache: _cellCache, - cellDataLoader: GridCellDataLoader(gridCell: _gridCell), + cellDataLoader: cellDataLoader, cellDataPersistence: CellDataPersistence(gridCell: _gridCell), ); } @@ -141,10 +162,7 @@ class _GridCellContext extends Equatable { } onCellChangedFn() { - final value = _cellDataNotifier.value; - if (value is T) { - onCellChanged(value); - } + onCellChanged(_cellDataNotifier.value as T); if (cellDataLoader.config.reloadOnCellChanged) { _loadData(); @@ -159,9 +177,9 @@ class _GridCellContext extends Equatable { _cellDataNotifier.removeListener(fn); } - T? getCellData() { + T? getCellData({bool loadIfNoCache = true}) { final data = cellCache.get(_cacheKey); - if (data == null) { + if (data == null && loadIfNoCache) { _loadData(); } return data; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/data_loader.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/data_loader.dart index 5be0435323..c223347715 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/data_loader.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/data_loader.dart @@ -4,8 +4,8 @@ abstract class IGridCellDataConfig { // The cell data will reload if it receives the field's change notification. bool get reloadOnFieldChanged; - // The cell data will reload if it receives the cell's change notification. - // For example, the number cell should be reloaded after user input the number. + // When the reloadOnCellChanged is true, it will load the cell data after user input. + // For example: The number cell reload the cell data that carries the format // user input: 12 // cell display: $12 bool get reloadOnCellChanged; @@ -30,60 +30,45 @@ abstract class IGridCellDataLoader { IGridCellDataConfig get config; } -class GridCellDataLoader extends IGridCellDataLoader { +abstract class ICellDataParser { + T? parserData(List data); +} + +class GridCellDataLoader extends IGridCellDataLoader { final CellService service = CellService(); final GridCell gridCell; + final ICellDataParser parser; @override final IGridCellDataConfig config; GridCellDataLoader({ required this.gridCell, + required this.parser, this.config = const GridCellDataConfig(), }); @override - Future loadData() { + Future loadData() { final fut = service.getCell( gridId: gridCell.gridId, fieldId: gridCell.field.id, rowId: gridCell.rowId, ); - return fut.then((result) { - return result.fold((data) => data, (err) { + return fut.then( + (result) => result.fold((Cell cell) { + try { + return parser.parserData(cell.data); + } catch (e, s) { + Log.error('$parser parser cellData failed, $e'); + Log.error('Stack trace \n $s'); + return null; + } + }, (err) { Log.error(err); return null; - }); - }); - } -} - -class DateCellDataLoader extends IGridCellDataLoader { - final GridCell gridCell; - final IGridCellDataConfig _config; - DateCellDataLoader({ - required this.gridCell, - }) : _config = const GridCellDataConfig(reloadOnFieldChanged: true); - - @override - IGridCellDataConfig get config => _config; - - @override - Future loadData() { - final payload = CellIdentifierPayload.create() - ..gridId = gridCell.gridId - ..fieldId = gridCell.field.id - ..rowId = gridCell.rowId; - - return GridEventGetDateCellData(payload).send().then((result) { - return result.fold( - (data) => data, - (err) { - Log.error(err); - return null; - }, - ); - }); + }), + ); } } @@ -109,3 +94,40 @@ class SelectOptionCellDataLoader extends IGridCellDataLoader const GridCellDataConfig(reloadOnFieldChanged: true); } + +class StringCellDataParser implements ICellDataParser { + @override + String? parserData(List data) { + return utf8.decode(data); + } +} + +class DateCellDataParser implements ICellDataParser { + @override + DateCellData? parserData(List data) { + if (data.isEmpty) { + return null; + } + return DateCellData.fromBuffer(data); + } +} + +class SelectOptionCellDataParser implements ICellDataParser { + @override + SelectOptionCellData? parserData(List data) { + if (data.isEmpty) { + return null; + } + return SelectOptionCellData.fromBuffer(data); + } +} + +class URLCellDataParser implements ICellDataParser { + @override + Cell? parserData(List data) { + if (data.isEmpty) { + return null; + } + return Cell.fromBuffer(data); + } +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart index cecfaa2f04..514ae2ce4e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart @@ -1,4 +1,3 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; @@ -16,15 +15,15 @@ class CheckboxCellBloc extends Bloc { }) : super(CheckboxCellState.initial(cellContext)) { on( (event, emit) async { - await event.map( - initial: (_Initial value) { + await event.when( + initial: () { _startListening(); }, - select: (_Selected value) async { + select: () async { _updateCellData(); }, - didReceiveCellUpdate: (_DidReceiveCellUpdate value) { - emit(state.copyWith(isSelected: _isSelected(value.cell))); + didReceiveCellUpdate: (cellData) { + emit(state.copyWith(isSelected: _isSelected(cellData))); }, ); }, @@ -43,9 +42,9 @@ class CheckboxCellBloc extends Bloc { } void _startListening() { - _onCellChangedFn = cellContext.startListening(onCellChanged: ((cell) { + _onCellChangedFn = cellContext.startListening(onCellChanged: ((cellData) { if (!isClosed) { - add(CheckboxCellEvent.didReceiveCellUpdate(cell)); + add(CheckboxCellEvent.didReceiveCellUpdate(cellData)); } })); } @@ -59,7 +58,7 @@ class CheckboxCellBloc extends Bloc { class CheckboxCellEvent with _$CheckboxCellEvent { const factory CheckboxCellEvent.initial() = _Initial; const factory CheckboxCellEvent.select() = _Selected; - const factory CheckboxCellEvent.didReceiveCellUpdate(Cell cell) = _DidReceiveCellUpdate; + const factory CheckboxCellEvent.didReceiveCellUpdate(String cellData) = _DidReceiveCellUpdate; } @freezed @@ -73,7 +72,6 @@ class CheckboxCellState with _$CheckboxCellState { } } -bool _isSelected(Cell? cell) { - final content = cell?.content ?? ""; - return content == "Yes"; +bool _isSelected(String? cellData) { + return cellData == "Yes"; } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart index 217ae4d384..ceb89bc201 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart @@ -1,4 +1,3 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; @@ -20,7 +19,7 @@ class NumberCellBloc extends Bloc { _startListening(); }, didReceiveCellUpdate: (_DidReceiveCellUpdate value) { - emit(state.copyWith(content: value.cell.content)); + emit(state.copyWith(content: value.cellContent)); }, updateCell: (_UpdateCell value) async { await _updateCellValue(value, emit); @@ -46,9 +45,9 @@ class NumberCellBloc extends Bloc { void _startListening() { _onCellChangedFn = cellContext.startListening( - onCellChanged: ((cell) { + onCellChanged: ((cellContent) { if (!isClosed) { - add(NumberCellEvent.didReceiveCellUpdate(cell)); + add(NumberCellEvent.didReceiveCellUpdate(cellContent)); } }), ); @@ -59,7 +58,7 @@ class NumberCellBloc extends Bloc { class NumberCellEvent with _$NumberCellEvent { const factory NumberCellEvent.initial() = _Initial; const factory NumberCellEvent.updateCell(String text) = _UpdateCell; - const factory NumberCellEvent.didReceiveCellUpdate(Cell cell) = _DidReceiveCellUpdate; + const factory NumberCellEvent.didReceiveCellUpdate(String cellContent) = _DidReceiveCellUpdate; } @freezed @@ -69,7 +68,7 @@ class NumberCellState with _$NumberCellState { }) = _NumberCellState; factory NumberCellState.initial(GridCellContext context) { - final cell = context.getCellData(); - return NumberCellState(content: cell?.content ?? ""); + final cellContent = context.getCellData() ?? ""; + return NumberCellState(content: cellContent); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_cell_bloc.dart index 056b65e556..0b6b1fd4ab 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_cell_bloc.dart @@ -21,7 +21,6 @@ class SelectOptionCellBloc extends Bloc options, List selectedOptions, ) = _DidReceiveOptions; } @@ -66,7 +63,6 @@ class SelectOptionCellEvent with _$SelectOptionCellEvent { @freezed class SelectOptionCellState with _$SelectOptionCellState { const factory SelectOptionCellState({ - required List options, required List selectedOptions, }) = _SelectOptionCellState; @@ -74,7 +70,6 @@ class SelectOptionCellState with _$SelectOptionCellState { final data = context.getCellData(); return SelectOptionCellState( - options: data?.options ?? [], selectedOptions: data?.selectOptions ?? [], ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_editor_bloc.dart index a1e1315682..87eabdf759 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_editor_bloc.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'package:app_flowy/workspace/application/grid/field/grid_listenr.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; @@ -13,17 +14,21 @@ part 'select_option_editor_bloc.freezed.dart'; class SelectOptionCellEditorBloc extends Bloc { final SelectOptionService _selectOptionService; final GridSelectOptionCellContext cellContext; + late final GridFieldsListener _fieldListener; void Function()? _onCellChangedFn; + Timer? _delayOperation; SelectOptionCellEditorBloc({ required this.cellContext, }) : _selectOptionService = SelectOptionService(gridCell: cellContext.gridCell), + _fieldListener = GridFieldsListener(gridId: cellContext.gridId), super(SelectOptionEditorState.initial(cellContext)) { on( (event, emit) async { await event.map( initial: (_Initial value) async { _startListening(); + _loadOptions(); }, didReceiveOptions: (_DidReceiveOptions value) { final result = _makeOptions(state.filter, value.options); @@ -63,6 +68,8 @@ class SelectOptionCellEditorBloc extends Bloc add(SelectOptionEditorEvent.didReceiveOptions(data.options, data.selectOptions)), + (err) { + Log.error(err); + return null; + }, + ); + }); + }); + } + _MakeOptionResult _makeOptions(Option filter, List allOptions) { final List options = List.from(allOptions); Option createOption = filter; @@ -135,13 +160,21 @@ class SelectOptionCellEditorBloc extends Bloc Log.error(err), + ); + }); } } @@ -168,7 +201,7 @@ class SelectOptionEditorState with _$SelectOptionEditorState { }) = _SelectOptionEditorState; factory SelectOptionEditorState.initial(GridSelectOptionCellContext context) { - final data = context.getCellData(); + final data = context.getCellData(loadIfNoCache: false); return SelectOptionEditorState( options: data?.options ?? [], allOptions: data?.options ?? [], diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart index 0b8b8be5e0..c29a14d696 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/text_cell_bloc.dart @@ -1,4 +1,3 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; @@ -14,21 +13,16 @@ class TextCellBloc extends Bloc { }) : super(TextCellState.initial(cellContext)) { on( (event, emit) async { - await event.map( - initial: (_InitialCell value) async { + await event.when( + initial: () async { _startListening(); }, - updateText: (_UpdateText value) { - cellContext.saveCellData(value.text); - emit(state.copyWith(content: value.text)); + updateText: (text) { + cellContext.saveCellData(text); + emit(state.copyWith(content: text)); }, - didReceiveCellData: (_DidReceiveCellData value) { - emit(state.copyWith(content: value.cellData.cell?.content ?? "")); - }, - didReceiveCellUpdate: (_DidReceiveCellUpdate value) { - emit(state.copyWith( - content: value.cell.content, - )); + didReceiveCellUpdate: (content) { + emit(state.copyWith(content: content)); }, ); }, @@ -47,9 +41,9 @@ class TextCellBloc extends Bloc { void _startListening() { _onCellChangedFn = cellContext.startListening( - onCellChanged: ((cell) { + onCellChanged: ((cellContent) { if (!isClosed) { - add(TextCellEvent.didReceiveCellUpdate(cell)); + add(TextCellEvent.didReceiveCellUpdate(cellContent)); } }), ); @@ -59,8 +53,7 @@ class TextCellBloc extends Bloc { @freezed class TextCellEvent with _$TextCellEvent { const factory TextCellEvent.initial() = _InitialCell; - const factory TextCellEvent.didReceiveCellData(GridCell cellData) = _DidReceiveCellData; - const factory TextCellEvent.didReceiveCellUpdate(Cell cell) = _DidReceiveCellUpdate; + const factory TextCellEvent.didReceiveCellUpdate(String cellContent) = _DidReceiveCellUpdate; const factory TextCellEvent.updateText(String text) = _UpdateText; } @@ -71,6 +64,6 @@ class TextCellState with _$TextCellState { }) = _TextCellState; factory TextCellState.initial(GridCellContext context) => TextCellState( - content: context.getCellData()?.content ?? "", + content: context.getCellData() ?? "", ); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart index bf4964054e..0149f63b3a 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart @@ -392,20 +392,3 @@ class GridEventUpdateDateCell { } } -class GridEventGetDateCellData { - CellIdentifierPayload request; - GridEventGetDateCellData(this.request); - - Future> send() { - final request = FFIRequest.create() - ..event = GridEvent.GetDateCellData.toString() - ..payload = requestToBytes(this.request); - - return Dispatch.asyncRequest(request) - .then((bytesResult) => bytesResult.fold( - (okBytes) => left(DateCellData.fromBuffer(okBytes)), - (errBytes) => right(FlowyError.fromBuffer(errBytes)), - )); - } -} - 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 a1ecd8c059..87f9036c88 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 @@ -1366,24 +1366,19 @@ class GridBlock extends $pb.GeneratedMessage { class Cell extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Cell', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'content') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY) ..hasRequiredFields = false ; Cell._() : super(); factory Cell({ $core.String? fieldId, - $core.String? content, - $core.String? data, + $core.List<$core.int>? data, }) { final _result = create(); if (fieldId != null) { _result.fieldId = fieldId; } - if (content != null) { - _result.content = content; - } if (data != null) { _result.data = data; } @@ -1420,22 +1415,13 @@ class Cell extends $pb.GeneratedMessage { void clearFieldId() => clearField(1); @$pb.TagNumber(2) - $core.String get content => $_getSZ(1); + $core.List<$core.int> get data => $_getN(1); @$pb.TagNumber(2) - set content($core.String v) { $_setString(1, v); } + set data($core.List<$core.int> v) { $_setBytes(1, v); } @$pb.TagNumber(2) - $core.bool hasContent() => $_has(1); + $core.bool hasData() => $_has(1); @$pb.TagNumber(2) - void clearContent() => clearField(2); - - @$pb.TagNumber(3) - $core.String get data => $_getSZ(2); - @$pb.TagNumber(3) - set data($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasData() => $_has(2); - @$pb.TagNumber(3) - void clearData() => clearField(3); + void clearData() => clearField(2); } class RepeatedCell extends $pb.GeneratedMessage { 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 c4f25d7fe3..7c28fa1ceb 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 @@ -290,13 +290,12 @@ const Cell$json = const { '1': 'Cell', '2': const [ const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'content', '3': 2, '4': 1, '5': 9, '10': 'content'}, - const {'1': 'data', '3': 3, '4': 1, '5': 9, '10': 'data'}, + const {'1': 'data', '3': 2, '4': 1, '5': 12, '10': 'data'}, ], }; /// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhgKB2NvbnRlbnQYAiABKAlSB2NvbnRlbnQSEgoEZGF0YRgDIAEoCVIEZGF0YQ=='); +final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhIKBGRhdGEYAiABKAxSBGRhdGE='); @$core.Deprecated('Use repeatedCellDescriptor instead') const RepeatedCell$json = const { '1': 'RepeatedCell', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart index 341dcf8d6a..863162cc3e 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart @@ -33,7 +33,6 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent UpdateCell = GridEvent._(71, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); static const GridEvent UpdateSelectOptionCell = GridEvent._(72, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateSelectOptionCell'); static const GridEvent UpdateDateCell = GridEvent._(80, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateDateCell'); - static const GridEvent GetDateCellData = GridEvent._(90, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetDateCellData'); static const $core.List values = [ GetGridData, @@ -59,7 +58,6 @@ class GridEvent extends $pb.ProtobufEnum { UpdateCell, UpdateSelectOptionCell, UpdateDateCell, - GetDateCellData, ]; static final $core.Map<$core.int, GridEvent> _byValue = $pb.ProtobufEnum.initByValue(values); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart index 58a712a4da..08de369a01 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart @@ -35,9 +35,8 @@ const GridEvent$json = const { const {'1': 'UpdateCell', '2': 71}, const {'1': 'UpdateSelectOptionCell', '2': 72}, const {'1': 'UpdateDateCell', '2': 80}, - const {'1': 'GetDateCellData', '2': 90}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIZChVVcGRhdGVGaWVsZFR5cGVPcHRpb24QDBIPCgtJbnNlcnRGaWVsZBANEg8KC0RlbGV0ZUZpZWxkEA4SEQoNU3dpdGNoVG9GaWVsZBAUEhIKDkR1cGxpY2F0ZUZpZWxkEBUSDAoITW92ZUl0ZW0QFhIWChJHZXRGaWVsZFR5cGVPcHRpb24QFxIZChVDcmVhdGVGaWVsZFR5cGVPcHRpb24QGBITCg9OZXdTZWxlY3RPcHRpb24QHhIbChdHZXRTZWxlY3RPcHRpb25DZWxsRGF0YRAfEhYKElVwZGF0ZVNlbGVjdE9wdGlvbhAgEg0KCUNyZWF0ZVJvdxAyEgoKBkdldFJvdxAzEg0KCURlbGV0ZVJvdxA0EhAKDER1cGxpY2F0ZVJvdxA1EgsKB0dldENlbGwQRhIOCgpVcGRhdGVDZWxsEEcSGgoWVXBkYXRlU2VsZWN0T3B0aW9uQ2VsbBBIEhIKDlVwZGF0ZURhdGVDZWxsEFASEwoPR2V0RGF0ZUNlbGxEYXRhEFo='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIZChVVcGRhdGVGaWVsZFR5cGVPcHRpb24QDBIPCgtJbnNlcnRGaWVsZBANEg8KC0RlbGV0ZUZpZWxkEA4SEQoNU3dpdGNoVG9GaWVsZBAUEhIKDkR1cGxpY2F0ZUZpZWxkEBUSDAoITW92ZUl0ZW0QFhIWChJHZXRGaWVsZFR5cGVPcHRpb24QFxIZChVDcmVhdGVGaWVsZFR5cGVPcHRpb24QGBITCg9OZXdTZWxlY3RPcHRpb24QHhIbChdHZXRTZWxlY3RPcHRpb25DZWxsRGF0YRAfEhYKElVwZGF0ZVNlbGVjdE9wdGlvbhAgEg0KCUNyZWF0ZVJvdxAyEgoKBkdldFJvdxAzEg0KCURlbGV0ZVJvdxA0EhAKDER1cGxpY2F0ZVJvdxA1EgsKB0dldENlbGwQRhIOCgpVcGRhdGVDZWxsEEcSGgoWVXBkYXRlU2VsZWN0T3B0aW9uQ2VsbBBIEhIKDlVwZGF0ZURhdGVDZWxsEFA='); diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 05847f8cc1..fe9a160b39 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -4,7 +4,7 @@ use crate::{ errors::FlowyResult, event_map::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser}, services::{ - folder_editor::ClientFolderEditor, persistence::FolderPersistence, set_current_workspace, AppController, + folder_editor::FolderEditor, persistence::FolderPersistence, set_current_workspace, AppController, TrashController, ViewController, WorkspaceController, }, }; @@ -61,7 +61,7 @@ pub struct FolderManager { pub(crate) view_controller: Arc, pub(crate) trash_controller: Arc, web_socket: Arc, - folder_editor: Arc>>>, + folder_editor: Arc>>>, data_processors: ViewDataProcessorMap, } @@ -166,8 +166,7 @@ impl FolderManager { let rev_persistence = Arc::new(RevisionPersistence::new(user_id, folder_id.as_ref(), disk_cache)); let rev_manager = RevisionManager::new(user_id, folder_id.as_ref(), rev_persistence); - let folder_editor = - ClientFolderEditor::new(user_id, &folder_id, token, rev_manager, self.web_socket.clone()).await?; + let folder_editor = FolderEditor::new(user_id, &folder_id, token, rev_manager, self.web_socket.clone()).await?; *self.folder_editor.write().await = Some(Arc::new(folder_editor)); let _ = self.app_controller.initialize()?; @@ -228,7 +227,7 @@ impl DefaultFolderBuilder { #[cfg(feature = "flowy_unit_test")] impl FolderManager { - pub async fn folder_editor(&self) -> Arc { + pub async fn folder_editor(&self) -> Arc { self.folder_editor.read().await.clone().unwrap() } } diff --git a/frontend/rust-lib/flowy-folder/src/services/app/event_handler.rs b/frontend/rust-lib/flowy-folder/src/services/app/event_handler.rs index 45034646b0..b95b91dc2e 100644 --- a/frontend/rust-lib/flowy-folder/src/services/app/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/services/app/event_handler.rs @@ -46,7 +46,7 @@ pub(crate) async fn update_app_handler( Ok(()) } -#[tracing::instrument(level = "debug", skip(data, app_controller, view_controller))] +#[tracing::instrument(level = "trace", skip(data, app_controller, view_controller))] pub(crate) async fn read_app_handler( data: Data, app_controller: AppData>, diff --git a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs index 6ea1a7e2ec..ef94c1d316 100644 --- a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs +++ b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs @@ -17,7 +17,7 @@ use lib_ot::core::PlainTextAttributes; use parking_lot::RwLock; use std::sync::Arc; -pub struct ClientFolderEditor { +pub struct FolderEditor { user_id: String, #[allow(dead_code)] pub(crate) folder_id: FolderId, @@ -27,7 +27,7 @@ pub struct ClientFolderEditor { ws_manager: Arc, } -impl ClientFolderEditor { +impl FolderEditor { #[allow(unused_variables)] pub async fn new( user_id: &str, @@ -129,7 +129,7 @@ impl RevisionCloudService for FolderRevisionCloudService { } #[cfg(feature = "flowy_unit_test")] -impl ClientFolderEditor { +impl FolderEditor { pub fn rev_manager(&self) -> Arc { self.rev_manager.clone() } diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs index b272168e33..d5bbb3a277 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs @@ -5,7 +5,7 @@ mod version_2; use crate::{ event_map::WorkspaceDatabase, manager::FolderId, - services::{folder_editor::ClientFolderEditor, persistence::migration::FolderMigration}, + services::{folder_editor::FolderEditor, persistence::migration::FolderMigration}, }; use flowy_database::ConnectionPool; use flowy_error::{FlowyError, FlowyResult}; @@ -50,14 +50,11 @@ pub trait FolderPersistenceTransaction { pub struct FolderPersistence { database: Arc, - folder_editor: Arc>>>, + folder_editor: Arc>>>, } impl FolderPersistence { - pub fn new( - database: Arc, - folder_editor: Arc>>>, - ) -> Self { + pub fn new(database: Arc, folder_editor: Arc>>>) -> Self { Self { database, folder_editor, diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs index 8dafda3c93..40f72e10b0 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs @@ -1,5 +1,5 @@ use crate::services::{ - folder_editor::ClientFolderEditor, + folder_editor::FolderEditor, persistence::{AppChangeset, FolderPersistenceTransaction, ViewChangeset, WorkspaceChangeset}, }; use flowy_error::{FlowyError, FlowyResult}; @@ -11,7 +11,7 @@ use flowy_folder_data_model::entities::{ }; use std::sync::Arc; -impl FolderPersistenceTransaction for ClientFolderEditor { +impl FolderPersistenceTransaction for FolderEditor { fn create_workspace(&self, _user_id: &str, workspace: Workspace) -> FlowyResult<()> { if let Some(change) = self.folder.write().create_workspace(workspace)? { let _ = self.apply_change(change)?; diff --git a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs index 603b76ec2c..ae88073afc 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -129,7 +129,7 @@ impl ViewController { .await } - #[tracing::instrument(level = "debug", skip(self), err)] + #[tracing::instrument(level = "trace", skip(self), err)] pub(crate) fn set_latest_view(&self, view_id: &str) -> Result<(), FlowyError> { KV::set_str(LATEST_VIEW_ID, view_id.to_owned()); Ok(()) @@ -193,7 +193,7 @@ impl ViewController { } // belong_to_id will be the app_id or view_id. - #[tracing::instrument(level = "debug", skip(self), err)] + #[tracing::instrument(level = "trace", skip(self), err)] pub(crate) async fn read_views_belong_to(&self, belong_to_id: &str) -> Result { self.persistence .begin_transaction(|transaction| { diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index a6fd1fbe29..39f023ca7d 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs @@ -1,5 +1,5 @@ use flowy_folder::event_map::FolderEvent::*; -use flowy_folder::{errors::ErrorCode, services::folder_editor::ClientFolderEditor}; +use flowy_folder::{errors::ErrorCode, services::folder_editor::FolderEditor}; use flowy_folder_data_model::entities::view::{RepeatedViewId, ViewId}; use flowy_folder_data_model::entities::workspace::WorkspaceId; use flowy_folder_data_model::entities::{ @@ -125,7 +125,7 @@ impl FolderTest { pub async fn run_script(&mut self, script: FolderScript) { let sdk = &self.sdk; - let folder_editor: Arc = sdk.folder_manager.folder_editor().await; + let folder_editor: Arc = sdk.folder_manager.folder_editor().await; let rev_manager = folder_editor.rev_manager(); let cache = rev_manager.revision_cache().await; diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index eda9840747..7374515793 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -7,7 +7,7 @@ use flowy_grid_data_model::entities::*; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; -#[tracing::instrument(level = "debug", skip(data, manager), err)] +#[tracing::instrument(level = "trace", skip(data, manager), err)] pub(crate) async fn get_grid_data_handler( data: Data, manager: AppData>, @@ -34,7 +34,7 @@ pub(crate) async fn get_grid_blocks_handler( data_result(repeated_grid_block) } -#[tracing::instrument(level = "debug", skip(data, manager), err)] +#[tracing::instrument(level = "trace", skip(data, manager), err)] pub(crate) async fn get_fields_handler( data: Data, manager: AppData>, @@ -47,7 +47,7 @@ pub(crate) async fn get_fields_handler( data_result(repeated_field) } -#[tracing::instrument(level = "debug", skip(data, manager), err)] +#[tracing::instrument(level = "trace", skip(data, manager), err)] pub(crate) async fn update_field_handler( data: Data, manager: AppData>, @@ -58,7 +58,7 @@ pub(crate) async fn update_field_handler( Ok(()) } -#[tracing::instrument(level = "debug", skip(data, manager), err)] +#[tracing::instrument(level = "trace", skip(data, manager), err)] pub(crate) async fn insert_field_handler( data: Data, manager: AppData>, @@ -69,7 +69,7 @@ pub(crate) async fn insert_field_handler( Ok(()) } -#[tracing::instrument(level = "debug", skip(data, manager), err)] +#[tracing::instrument(level = "trace", skip(data, manager), err)] pub(crate) async fn update_field_type_option_handler( data: Data, manager: AppData>, @@ -82,7 +82,7 @@ pub(crate) async fn update_field_type_option_handler( Ok(()) } -#[tracing::instrument(level = "debug", skip(data, manager), err)] +#[tracing::instrument(level = "trace", skip(data, manager), err)] pub(crate) async fn delete_field_handler( data: Data, manager: AppData>, @@ -93,7 +93,7 @@ pub(crate) async fn delete_field_handler( Ok(()) } -#[tracing::instrument(level = "debug", skip(data, manager), err)] +#[tracing::instrument(level = "trace", skip(data, manager), err)] pub(crate) async fn switch_to_field_handler( data: Data, manager: AppData>, @@ -120,7 +120,7 @@ pub(crate) async fn switch_to_field_handler( data_result(data) } -#[tracing::instrument(level = "debug", skip(data, manager), err)] +#[tracing::instrument(level = "trace", skip(data, manager), err)] pub(crate) async fn duplicate_field_handler( data: Data, manager: AppData>, @@ -132,7 +132,7 @@ pub(crate) async fn duplicate_field_handler( } /// Return the FieldTypeOptionData if the Field exists otherwise return record not found error. -#[tracing::instrument(level = "debug", skip(data, manager), err)] +#[tracing::instrument(level = "trace", skip(data, manager), err)] pub(crate) async fn get_field_type_option_data_handler( data: Data, manager: AppData>, @@ -154,7 +154,7 @@ pub(crate) async fn get_field_type_option_data_handler( } /// Create FieldMeta and save it. Return the FieldTypeOptionData. -#[tracing::instrument(level = "debug", skip(data, manager), err)] +#[tracing::instrument(level = "trace", skip(data, manager), err)] pub(crate) async fn create_field_type_option_data_handler( data: Data, manager: AppData>, @@ -171,7 +171,7 @@ pub(crate) async fn create_field_type_option_data_handler( }) } -#[tracing::instrument(level = "debug", skip(data, manager), err)] +#[tracing::instrument(level = "trace", skip(data, manager), err)] pub(crate) async fn move_item_handler( data: Data, manager: AppData>, @@ -252,7 +252,7 @@ pub(crate) async fn get_cell_handler( } } -#[tracing::instrument(level = "debug", skip_all, err)] +#[tracing::instrument(level = "trace", skip_all, err)] pub(crate) async fn update_cell_handler( data: Data, manager: AppData>, @@ -263,28 +263,7 @@ pub(crate) async fn update_cell_handler( Ok(()) } -#[tracing::instrument(level = "trace", skip(data, manager), err)] -pub(crate) async fn get_date_cell_data_handler( - data: Data, - manager: AppData>, -) -> DataResult { - let params: CellIdentifier = data.into_inner().try_into()?; - let editor = manager.get_grid_editor(¶ms.grid_id)?; - match editor.get_field_meta(¶ms.field_id).await { - None => { - tracing::error!("Can't find the date field with id: {}", params.field_id); - data_result(DateCellData::default()) - } - Some(field_meta) => { - let cell_meta = editor.get_cell_meta(¶ms.row_id, ¶ms.field_id).await?; - let type_option = DateTypeOption::from(&field_meta); - let date_cell_data = type_option.make_date_cell_data(&cell_meta)?; - data_result(date_cell_data) - } - } -} - -#[tracing::instrument(level = "debug", skip_all, err)] +#[tracing::instrument(level = "trace", skip_all, err)] pub(crate) async fn new_select_option_handler( data: Data, manager: AppData>, @@ -301,7 +280,7 @@ pub(crate) async fn new_select_option_handler( } } -#[tracing::instrument(level = "debug", skip_all, err)] +#[tracing::instrument(level = "trace", skip_all, err)] pub(crate) async fn update_select_option_handler( data: Data, manager: AppData>, @@ -341,7 +320,7 @@ pub(crate) async fn update_select_option_handler( Ok(()) } -#[tracing::instrument(level = "debug", skip(data, manager), err)] +#[tracing::instrument(level = "trace", skip(data, manager), err)] pub(crate) async fn get_select_option_handler( data: Data, manager: AppData>, @@ -362,7 +341,7 @@ pub(crate) async fn get_select_option_handler( } } -#[tracing::instrument(level = "debug", skip_all, err)] +#[tracing::instrument(level = "trace", skip_all, err)] pub(crate) async fn update_select_option_cell_handler( data: Data, manager: AppData>, @@ -373,7 +352,7 @@ pub(crate) async fn update_select_option_cell_handler( Ok(()) } -#[tracing::instrument(level = "debug", skip_all, err)] +#[tracing::instrument(level = "trace", skip_all, err)] pub(crate) async fn update_date_cell_handler( data: Data, manager: AppData>, diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index c740eee6d8..48e5fd9b6c 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -29,7 +29,6 @@ pub fn create(grid_manager: Arc) -> Module { // Cell .event(GridEvent::GetCell, get_cell_handler) .event(GridEvent::UpdateCell, update_cell_handler) - .event(GridEvent::GetDateCellData, get_date_cell_data_handler) // SelectOption .event(GridEvent::NewSelectOption, new_select_option_handler) .event(GridEvent::UpdateSelectOption, update_select_option_handler) @@ -112,7 +111,4 @@ pub enum GridEvent { #[event(input = "DateChangesetPayload")] UpdateDateCell = 80, - - #[event(input = "CellIdentifierPayload", output = "DateCellData")] - GetDateCellData = 90, } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 218dff8782..f8ea9e70ae 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -1,5 +1,5 @@ -use crate::services::grid_editor::ClientGridEditor; -use crate::services::persistence::block_index::BlockIndexPersistence; +use crate::services::grid_editor::GridMetaEditor; +use crate::services::persistence::block_index::BlockIndexCache; use crate::services::persistence::kv::GridKVPersistence; use crate::services::persistence::GridDatabase; use bytes::Bytes; @@ -20,9 +20,9 @@ pub trait GridUser: Send + Sync { } pub struct GridManager { - editor_map: Arc, + editor_map: Arc>>, grid_user: Arc, - block_index_persistence: Arc, + block_index_cache: Arc, #[allow(dead_code)] kv_persistence: Arc, } @@ -33,14 +33,14 @@ impl GridManager { _rev_web_socket: Arc, database: Arc, ) -> Self { - let grid_editors = Arc::new(GridEditorMap::new()); + let grid_editors = Arc::new(DashMap::new()); let kv_persistence = Arc::new(GridKVPersistence::new(database.clone())); - let block_index_persistence = Arc::new(BlockIndexPersistence::new(database)); + let block_index_persistence = Arc::new(BlockIndexCache::new(database)); Self { editor_map: grid_editors, grid_user, kv_persistence, - block_index_persistence, + block_index_cache: block_index_persistence, } } @@ -67,7 +67,7 @@ impl GridManager { } #[tracing::instrument(level = "debug", skip_all, fields(grid_id), err)] - pub async fn open_grid>(&self, grid_id: T) -> FlowyResult> { + pub async fn open_grid>(&self, grid_id: T) -> FlowyResult> { let grid_id = grid_id.as_ref(); tracing::Span::current().record("grid_id", &grid_id); self.get_or_create_grid_editor(grid_id).await @@ -90,23 +90,27 @@ impl GridManager { } // #[tracing::instrument(level = "debug", skip(self), err)] - pub fn get_grid_editor(&self, grid_id: &str) -> FlowyResult> { + pub fn get_grid_editor(&self, grid_id: &str) -> FlowyResult> { match self.editor_map.get(grid_id) { None => Err(FlowyError::internal().context("Should call open_grid function first")), - Some(editor) => Ok(editor), + Some(editor) => Ok(editor.clone()), } } - async fn get_or_create_grid_editor(&self, grid_id: &str) -> FlowyResult> { + async fn get_or_create_grid_editor(&self, grid_id: &str) -> FlowyResult> { match self.editor_map.get(grid_id) { None => { tracing::trace!("Create grid editor with id: {}", grid_id); let db_pool = self.grid_user.db_pool()?; let editor = self.make_grid_editor(grid_id, db_pool).await?; - self.editor_map.insert(grid_id, &editor); + + if self.editor_map.contains_key(grid_id) { + tracing::warn!("Grid:{} already exists in cache", grid_id); + } + self.editor_map.insert(grid_id.to_string(), editor.clone()); Ok(editor) } - Some(editor) => Ok(editor), + Some(editor) => Ok(editor.clone()), } } @@ -115,11 +119,10 @@ impl GridManager { &self, grid_id: &str, pool: Arc, - ) -> Result, FlowyError> { + ) -> Result, FlowyError> { let user = self.grid_user.clone(); let rev_manager = self.make_grid_rev_manager(grid_id, pool.clone())?; - let grid_editor = - ClientGridEditor::new(grid_id, user, rev_manager, self.block_index_persistence.clone()).await?; + let grid_editor = GridMetaEditor::new(grid_id, user, rev_manager, self.block_index_cache.clone()).await?; Ok(grid_editor) } @@ -145,31 +148,6 @@ impl GridManager { } } -pub struct GridEditorMap { - inner: DashMap>, -} - -impl GridEditorMap { - fn new() -> Self { - Self { inner: DashMap::new() } - } - - pub(crate) fn insert(&self, grid_id: &str, grid_editor: &Arc) { - if self.inner.contains_key(grid_id) { - tracing::warn!("Grid:{} already exists in cache", grid_id); - } - self.inner.insert(grid_id.to_string(), grid_editor.clone()); - } - - pub(crate) fn get(&self, grid_id: &str) -> Option> { - Some(self.inner.get(grid_id)?.clone()) - } - - pub(crate) fn remove(&self, grid_id: &str) { - self.inner.remove(grid_id); - } -} - pub async fn make_grid_view_data( user_id: &str, view_id: &str, @@ -192,9 +170,7 @@ pub async fn make_grid_view_data( // Indexing the block's rows build_context.block_meta_data.rows.iter().for_each(|row| { - let _ = grid_manager - .block_index_persistence - .insert_or_update(&row.block_id, &row.id); + let _ = grid_manager.block_index_cache.insert(&row.block_id, &row.id); }); // Create grid's block diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs index 6762254df7..73eaff920f 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs @@ -48,7 +48,6 @@ pub enum GridEvent { UpdateCell = 71, UpdateSelectOptionCell = 72, UpdateDateCell = 80, - GetDateCellData = 90, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -81,7 +80,6 @@ impl ::protobuf::ProtobufEnum for GridEvent { 71 => ::std::option::Option::Some(GridEvent::UpdateCell), 72 => ::std::option::Option::Some(GridEvent::UpdateSelectOptionCell), 80 => ::std::option::Option::Some(GridEvent::UpdateDateCell), - 90 => ::std::option::Option::Some(GridEvent::GetDateCellData), _ => ::std::option::Option::None } } @@ -111,7 +109,6 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::UpdateCell, GridEvent::UpdateSelectOptionCell, GridEvent::UpdateDateCell, - GridEvent::GetDateCellData, ]; values } @@ -140,7 +137,7 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xdc\x03\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xc7\x03\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ \x0bUpdateField\x10\x0b\x12\x19\n\x15UpdateFieldTypeOption\x10\x0c\x12\ \x0f\n\x0bInsertField\x10\r\x12\x0f\n\x0bDeleteField\x10\x0e\x12\x11\n\r\ @@ -151,7 +148,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x10\x20\x12\r\n\tCreateRow\x102\x12\n\n\x06GetRow\x103\x12\r\n\tDeleteR\ ow\x104\x12\x10\n\x0cDuplicateRow\x105\x12\x0b\n\x07GetCell\x10F\x12\x0e\ \n\nUpdateCell\x10G\x12\x1a\n\x16UpdateSelectOptionCell\x10H\x12\x12\n\ - \x0eUpdateDateCell\x10P\x12\x13\n\x0fGetDateCellData\x10Zb\x06proto3\ + \x0eUpdateDateCell\x10Pb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto index 10e98a2934..623bf4b7da 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto @@ -24,5 +24,4 @@ enum GridEvent { UpdateCell = 71; UpdateSelectOptionCell = 72; UpdateDateCell = 80; - GetDateCellData = 90; } diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index ce7c5c8e8d..d1cb847b37 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -8,18 +8,17 @@ use flowy_sync::util::make_delta_from_revisions; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; use std::borrow::Cow; - use std::sync::Arc; use tokio::sync::RwLock; -pub struct ClientGridBlockMetaEditor { +pub struct GridBlockMetaEditor { user_id: String, pub block_id: String, pad: Arc>, rev_manager: Arc, } -impl ClientGridBlockMetaEditor { +impl GridBlockMetaEditor { pub async fn new( user_id: &str, token: &str, 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 229afe75a2..6ce36488c2 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 @@ -1,7 +1,7 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; -use crate::services::block_meta_editor::ClientGridBlockMetaEditor; -use crate::services::persistence::block_index::BlockIndexPersistence; +use crate::services::block_meta_editor::GridBlockMetaEditor; +use crate::services::persistence::block_index::BlockIndexCache; use crate::services::row::{group_row_orders, GridBlockSnapshot}; use dashmap::DashMap; use flowy_error::FlowyResult; @@ -15,20 +15,20 @@ use std::borrow::Cow; use std::collections::HashMap; use std::sync::Arc; -pub(crate) struct GridBlockMetaEditorManager { +type BlockId = String; +pub(crate) struct GridBlockManager { grid_id: String, user: Arc, - // Key: block_id - editor_map: DashMap>, - persistence: Arc, + persistence: Arc, + block_editor_map: DashMap>, } -impl GridBlockMetaEditorManager { +impl GridBlockManager { pub(crate) async fn new( grid_id: &str, user: &Arc, blocks: Vec, - persistence: Arc, + persistence: Arc, ) -> FlowyResult { let editor_map = make_block_meta_editor_map(user, blocks).await?; let user = user.clone(); @@ -36,27 +36,27 @@ impl GridBlockMetaEditorManager { let manager = Self { grid_id, user, - editor_map, + block_editor_map: editor_map, persistence, }; Ok(manager) } // #[tracing::instrument(level = "trace", skip(self))] - pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult> { + pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult> { debug_assert!(!block_id.is_empty()); - match self.editor_map.get(block_id) { + match self.block_editor_map.get(block_id) { None => { tracing::error!("The is a fatal error, block is not exist"); let editor = Arc::new(make_block_meta_editor(&self.user, block_id).await?); - self.editor_map.insert(block_id.to_owned(), editor.clone()); + self.block_editor_map.insert(block_id.to_owned(), editor.clone()); Ok(editor) } Some(editor) => Ok(editor.clone()), } } - async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { + async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { let block_id = self.persistence.get_block_id(row_id)?; Ok(self.get_editor(&block_id).await?) } @@ -67,7 +67,7 @@ impl GridBlockMetaEditorManager { row_meta: RowMeta, start_row_id: Option, ) -> FlowyResult { - let _ = self.persistence.insert_or_update(&row_meta.block_id, &row_meta.id)?; + let _ = self.persistence.insert(&row_meta.block_id, &row_meta.id)?; let editor = self.get_editor(&row_meta.block_id).await?; let mut index_row_order = IndexRowOrder::from(&row_meta); @@ -90,7 +90,7 @@ impl GridBlockMetaEditorManager { let editor = self.get_editor(&block_id).await?; let mut row_count = 0; for row in row_metas { - let _ = self.persistence.insert_or_update(&row.block_id, &row.id)?; + let _ = self.persistence.insert(&row.block_id, &row.id)?; let mut row_order = IndexRowOrder::from(&row); let (count, index) = editor.create_row(row, None).await?; row_count = count; @@ -256,7 +256,7 @@ impl GridBlockMetaEditorManager { async fn make_block_meta_editor_map( user: &Arc, blocks: Vec, -) -> FlowyResult>> { +) -> FlowyResult>> { let editor_map = DashMap::new(); for block in blocks { let editor = make_block_meta_editor(user, &block.block_id).await?; @@ -266,7 +266,7 @@ async fn make_block_meta_editor_map( Ok(editor_map) } -async fn make_block_meta_editor(user: &Arc, block_id: &str) -> FlowyResult { +async fn make_block_meta_editor(user: &Arc, block_id: &str) -> FlowyResult { let token = user.token()?; let user_id = user.user_id()?; let pool = user.db_pool()?; @@ -274,5 +274,5 @@ async fn make_block_meta_editor(user: &Arc, block_id: &str) -> Flo let disk_cache = Arc::new(SQLiteGridBlockMetaRevisionPersistence::new(&user_id, pool)); let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, block_id, disk_cache)); let rev_manager = RevisionManager::new(&user_id, block_id, rev_persistence); - ClientGridBlockMetaEditor::new(&user_id, &token, block_id, rev_manager).await + GridBlockMetaEditor::new(&user_id, &token, block_id, rev_manager).await } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs index 90bb53cea6..c8d14b6b03 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs @@ -58,7 +58,7 @@ impl CellDataOperation for CheckboxTypeOption { let encoded_data = encoded_data.into(); if encoded_data == YES || encoded_data == NO { - return Ok(DecodedCellData::from_content(encoded_data)); + return Ok(DecodedCellData::new(encoded_data)); } Ok(DecodedCellData::default()) @@ -104,37 +104,37 @@ mod tests { let field_meta = FieldBuilder::from_field_type(&FieldType::Checkbox).build(); let data = apply_cell_data_changeset("true", None, &field_meta).unwrap(); assert_eq!( - decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).content, + decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).to_string(), YES ); let data = apply_cell_data_changeset("1", None, &field_meta).unwrap(); assert_eq!( - decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).content, + decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).to_string(), YES ); let data = apply_cell_data_changeset("yes", None, &field_meta).unwrap(); assert_eq!( - decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).content, + decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).to_string(), YES ); let data = apply_cell_data_changeset("false", None, &field_meta).unwrap(); assert_eq!( - decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).content, + decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).to_string(), NO ); let data = apply_cell_data_changeset("no", None, &field_meta).unwrap(); assert_eq!( - decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).content, + decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).to_string(), NO ); let data = apply_cell_data_changeset("12", None, &field_meta).unwrap(); assert_eq!( - decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).content, + decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).to_string(), NO ); } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index 5ecca97105..25a16a0515 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -1,9 +1,7 @@ use crate::entities::{CellIdentifier, CellIdentifierPayload}; use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::{ - CellContentChangeset, CellDataOperation, DecodedCellData, EncodedCellData, TypeOptionCellData, -}; +use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellData, EncodedCellData}; use bytes::Bytes; use chrono::format::strftime::StrftimeItems; use chrono::NaiveDateTime; @@ -79,32 +77,12 @@ impl DateTypeOption { } } - pub fn make_date_cell_data(&self, cell_meta: &Option) -> FlowyResult { - if cell_meta.is_none() { - return Ok(DateCellData::default()); - } - - let json = &cell_meta.as_ref().unwrap().data; - let result = TypeOptionCellData::from_str(json); - if result.is_err() { - return Ok(DateCellData::default()); - } - - let serde_cell_data = DateCellDataSerde::from_str(&result.unwrap().data)?; - let date = self.decode_cell_data_from_timestamp(&serde_cell_data).content; - let time = serde_cell_data.time.unwrap_or_else(|| "".to_owned()); - let timestamp = serde_cell_data.timestamp; - - Ok(DateCellData { date, time, timestamp }) - } - - fn decode_cell_data_from_timestamp(&self, serde_cell_data: &DateCellDataSerde) -> DecodedCellData { + fn date_desc_from_timestamp(&self, serde_cell_data: &DateCellDataSerde) -> String { if serde_cell_data.timestamp == 0 { - return DecodedCellData::default(); + return "".to_owned(); } - let cell_content = self.today_desc_from_timestamp(serde_cell_data.timestamp, &serde_cell_data.time); - DecodedCellData::new(serde_cell_data.timestamp.to_string(), cell_content) + self.today_desc_from_timestamp(serde_cell_data.timestamp, &serde_cell_data.time) } fn timestamp_from_utc_with_time( @@ -156,7 +134,11 @@ impl CellDataOperation, DateCellDataSerde> fo } let encoded_data = encoded_data.into().try_into_inner()?; - Ok(self.decode_cell_data_from_timestamp(&encoded_data)) + let date = self.date_desc_from_timestamp(&encoded_data); + let time = encoded_data.time.unwrap_or_else(|| "".to_owned()); + let timestamp = encoded_data.timestamp; + + DecodedCellData::try_from_bytes(DateCellData { date, time, timestamp }) } fn apply_changeset(&self, changeset: C, _cell_meta: Option) -> Result @@ -417,20 +399,27 @@ impl std::convert::From for CellContentChangeset { #[cfg(test)] mod tests { use crate::services::field::FieldBuilder; - use crate::services::field::{DateCellContentChangeset, DateCellDataSerde, DateFormat, DateTypeOption, TimeFormat}; - use crate::services::row::{ - apply_cell_data_changeset, decode_cell_data_from_type_option_cell_data, CellDataOperation, EncodedCellData, + use crate::services::field::{ + DateCellContentChangeset, DateCellData, DateCellDataSerde, DateFormat, DateTypeOption, TimeFormat, }; + use crate::services::row::{CellDataOperation, EncodedCellData}; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use strum::IntoEnumIterator; #[test] fn date_description_invalid_input_test() { - let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); - let data = apply_cell_data_changeset("1e", None, &field_meta).unwrap(); - assert_eq!( - decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).content, - "".to_owned() + let type_option = DateTypeOption::default(); + let field_type = FieldType::DateTime; + let field_meta = FieldBuilder::from_field_type(&field_type).build(); + assert_changeset_result( + &type_option, + DateCellContentChangeset { + date: Some("1e".to_string()), + time: Some("23:00".to_owned()), + }, + &field_type, + &field_meta, + "", ); } @@ -442,40 +431,16 @@ mod tests { type_option.date_format = date_format; match date_format { DateFormat::Friendly => { - assert_eq!( - "Mar 14,2022".to_owned(), - type_option - .decode_cell_data(data(1647251762), &FieldType::DateTime, &field_meta) - .unwrap() - .content - ); + assert_decode_timestamp(1647251762, &type_option, &field_meta, "Mar 14,2022"); } DateFormat::US => { - assert_eq!( - "2022/03/14".to_owned(), - type_option - .decode_cell_data(data(1647251762), &FieldType::DateTime, &field_meta) - .unwrap() - .content - ); + assert_decode_timestamp(1647251762, &type_option, &field_meta, "2022/03/14"); } DateFormat::ISO => { - assert_eq!( - "2022-03-14".to_owned(), - type_option - .decode_cell_data(data(1647251762), &FieldType::DateTime, &field_meta) - .unwrap() - .content - ); + assert_decode_timestamp(1647251762, &type_option, &field_meta, "2022-03-14"); } DateFormat::Local => { - assert_eq!( - "2022/03/14".to_owned(), - type_option - .decode_cell_data(data(1647251762), &FieldType::DateTime, &field_meta) - .unwrap() - .content - ); + assert_decode_timestamp(1647251762, &type_option, &field_meta, "2022/03/14"); } } } @@ -483,43 +448,6 @@ mod tests { #[test] fn date_description_time_format_test() { - let mut type_option = DateTypeOption::default(); - let field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build(); - for time_format in TimeFormat::iter() { - type_option.time_format = time_format; - match time_format { - TimeFormat::TwentyFourHour => { - assert_eq!( - "Mar 14,2022".to_owned(), - type_option.today_desc_from_timestamp(1647251762, &None) - ); - assert_eq!( - "Mar 14,2022".to_owned(), - type_option - .decode_cell_data(data(1647251762), &FieldType::DateTime, &field_meta) - .unwrap() - .content - ); - } - TimeFormat::TwelveHour => { - assert_eq!( - "Mar 14,2022".to_owned(), - type_option.today_desc_from_timestamp(1647251762, &None) - ); - assert_eq!( - "Mar 14,2022".to_owned(), - type_option - .decode_cell_data(data(1647251762), &FieldType::DateTime, &field_meta) - .unwrap() - .content - ); - } - } - } - } - - #[test] - fn date_description_time_format_test2() { let mut type_option = DateTypeOption::default(); let field_type = FieldType::DateTime; let field_meta = FieldBuilder::from_field_type(&field_type).build(); @@ -529,7 +457,7 @@ mod tests { type_option.include_time = true; match time_format { TimeFormat::TwentyFourHour => { - assert_result( + assert_changeset_result( &type_option, DateCellContentChangeset { date: Some(1653609600.to_string()), @@ -539,7 +467,7 @@ mod tests { &field_meta, "May 27,2022 00:00", ); - assert_result( + assert_changeset_result( &type_option, DateCellContentChangeset { date: Some(1653609600.to_string()), @@ -551,7 +479,7 @@ mod tests { ); } TimeFormat::TwelveHour => { - assert_result( + assert_changeset_result( &type_option, DateCellContentChangeset { date: Some(1653609600.to_string()), @@ -562,7 +490,7 @@ mod tests { "May 27,2022 12:00 AM", ); - assert_result( + assert_changeset_result( &type_option, DateCellContentChangeset { date: Some(1653609600.to_string()), @@ -573,7 +501,7 @@ mod tests { "May 27,2022", ); - assert_result( + assert_changeset_result( &type_option, DateCellContentChangeset { date: Some(1653609600.to_string()), @@ -595,7 +523,7 @@ mod tests { let field_meta = FieldBuilder::from_field_type(&field_type).build(); let date_timestamp = "1653609600".to_owned(); - assert_result( + assert_changeset_result( &type_option, DateCellContentChangeset { date: Some(date_timestamp.clone()), @@ -607,7 +535,7 @@ mod tests { ); type_option.include_time = true; - assert_result( + assert_changeset_result( &type_option, DateCellContentChangeset { date: Some(date_timestamp.clone()), @@ -618,7 +546,7 @@ mod tests { "May 27,2022 00:00", ); - assert_result( + assert_changeset_result( &type_option, DateCellContentChangeset { date: Some(date_timestamp.clone()), @@ -630,7 +558,7 @@ mod tests { ); type_option.time_format = TimeFormat::TwelveHour; - assert_result( + assert_changeset_result( &type_option, DateCellContentChangeset { date: Some(date_timestamp), @@ -670,22 +598,39 @@ mod tests { type_option.apply_changeset("he", None).unwrap(); } - fn data(s: i64) -> String { - serde_json::to_string(&DateCellDataSerde::from_timestamp(s, None)).unwrap() - } - - fn assert_result( + fn assert_changeset_result( type_option: &DateTypeOption, changeset: DateCellContentChangeset, - field_type: &FieldType, + _field_type: &FieldType, field_meta: &FieldMeta, expected: &str, ) { let encoded_data = EncodedCellData(Some(type_option.apply_changeset(changeset, None).unwrap())); - let content = type_option - .decode_cell_data(encoded_data, field_type, field_meta) + assert_eq!( + expected.to_owned(), + decode_cell_data(encoded_data, type_option, field_meta) + ); + } + + fn assert_decode_timestamp(timestamp: i64, type_option: &DateTypeOption, field_meta: &FieldMeta, expected: &str) { + let serde_json = DateCellDataSerde { timestamp, time: None }.to_string(); + + assert_eq!( + expected.to_owned(), + decode_cell_data(serde_json, type_option, field_meta) + ); + } + + fn decode_cell_data>>( + encoded_data: T, + type_option: &DateTypeOption, + field_meta: &FieldMeta, + ) -> String { + type_option + .decode_cell_data(encoded_data, &FieldType::DateTime, &field_meta) .unwrap() - .content; - assert_eq!(expected.to_owned(), content); + .parse::() + .unwrap() + .date } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs index db6f7dffde..cf4bd22e3d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs @@ -94,22 +94,22 @@ impl CellDataOperation for NumberTypeOption { match self.format { NumberFormat::Number => { if let Ok(v) = cell_data.parse::() { - return Ok(DecodedCellData::from_content(v.to_string())); + return Ok(DecodedCellData::new(v.to_string())); } if let Ok(v) = cell_data.parse::() { - return Ok(DecodedCellData::from_content(v.to_string())); + return Ok(DecodedCellData::new(v.to_string())); } Ok(DecodedCellData::default()) } NumberFormat::Percent => { let content = cell_data.parse::().map_or(String::new(), |v| v.to_string()); - Ok(DecodedCellData::from_content(content)) + Ok(DecodedCellData::new(content)) } _ => { let content = self.money_from_str(&cell_data); - Ok(DecodedCellData::from_content(content)) + Ok(DecodedCellData::new(content)) } } } @@ -738,7 +738,7 @@ mod tests { type_option .decode_cell_data(cell_data, field_type, field_meta) .unwrap() - .content, + .to_string(), expected_str.to_owned() ); } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index c73dd1802f..1e857e9fd3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -109,16 +109,18 @@ impl CellDataOperation for SingleSelectTypeOption { return Ok(DecodedCellData::default()); } - let cell_data = encoded_data.into(); - if let Some(option_id) = select_option_ids(cell_data).first() { - let data = match self.options.iter().find(|option| &option.id == option_id) { - None => DecodedCellData::default(), - Some(option) => DecodedCellData::from_content(option.name.clone()), - }; - Ok(data) - } else { - Ok(DecodedCellData::default()) + let encoded_data = encoded_data.into(); + let mut cell_data = SelectOptionCellData { + options: self.options.clone(), + select_options: vec![], + }; + if let Some(option_id) = select_option_ids(encoded_data).first() { + if let Some(option) = self.options.iter().find(|option| &option.id == option_id) { + cell_data.select_options.push(option.clone()); + } } + + DecodedCellData::try_from_bytes(cell_data) } fn apply_changeset(&self, changeset: C, _cell_meta: Option) -> Result @@ -204,17 +206,21 @@ impl CellDataOperation for MultiSelectTypeOption { if !decoded_field_type.is_select_option() { return Ok(DecodedCellData::default()); } - let cell_data = encoded_data.into(); - let option_ids = select_option_ids(cell_data); - let content = self - .options - .iter() - .filter(|option| option_ids.contains(&option.id)) - .map(|option| option.name.clone()) - .collect::>() - .join(SELECTION_IDS_SEPARATOR); - Ok(DecodedCellData::from_content(content)) + tracing::info!("😁{}", self.options.len()); + + let encoded_data = encoded_data.into(); + let select_options = select_option_ids(encoded_data) + .into_iter() + .flat_map(|option_id| self.options.iter().find(|option| option.id == option_id).cloned()) + .collect::>(); + + let cell_data = SelectOptionCellData { + options: self.options.clone(), + select_options, + }; + + DecodedCellData::try_from_bytes(cell_data) } fn apply_changeset(&self, changeset: T, cell_meta: Option) -> Result @@ -280,7 +286,7 @@ fn select_option_ids(data: String) -> Vec { .collect::>() } -#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] pub struct SelectOption { #[pb(index = 1)] pub id: String, @@ -446,7 +452,7 @@ pub struct SelectOptionCellData { pub select_options: Vec, } -#[derive(ProtoBuf_Enum, Serialize, Deserialize, Debug, Clone)] +#[derive(ProtoBuf_Enum, PartialEq, Eq, Serialize, Deserialize, Debug, Clone)] #[repr(u8)] pub enum SelectOptionColor { Purple = 0, @@ -502,9 +508,10 @@ mod tests { use crate::services::field::FieldBuilder; use crate::services::field::{ MultiSelectTypeOption, MultiSelectTypeOptionBuilder, SelectOption, SelectOptionCellContentChangeset, - SingleSelectTypeOption, SingleSelectTypeOptionBuilder, SELECTION_IDS_SEPARATOR, + SelectOptionCellData, SingleSelectTypeOption, SingleSelectTypeOptionBuilder, SELECTION_IDS_SEPARATOR, }; use crate::services::row::CellDataOperation; + use flowy_grid_data_model::entities::FieldMeta; #[test] fn single_select_test() { @@ -526,47 +533,24 @@ mod tests { let option_ids = vec![google_option.id.clone(), facebook_option.id].join(SELECTION_IDS_SEPARATOR); let data = SelectOptionCellContentChangeset::from_insert(&option_ids).to_str(); let cell_data = type_option.apply_changeset(data, None).unwrap(); - assert_eq!( - type_option - .decode_cell_data(cell_data, &field_meta.field_type, &field_meta) - .unwrap() - .content, - google_option.name, - ); + assert_single_select_options(cell_data, &type_option, &field_meta, vec![google_option.clone()]); let data = SelectOptionCellContentChangeset::from_insert(&google_option.id).to_str(); let cell_data = type_option.apply_changeset(data, None).unwrap(); - assert_eq!( - type_option - .decode_cell_data(cell_data, &field_meta.field_type, &field_meta) - .unwrap() - .content, - google_option.name, - ); + assert_single_select_options(cell_data, &type_option, &field_meta, vec![google_option.clone()]); // Invalid option id let cell_data = type_option .apply_changeset(SelectOptionCellContentChangeset::from_insert("").to_str(), None) .unwrap(); - assert_eq!( - type_option - .decode_cell_data(cell_data, &field_meta.field_type, &field_meta) - .unwrap() - .content, - "", - ); + assert_single_select_options(cell_data, &type_option, &field_meta, vec![]); // Invalid option id let cell_data = type_option .apply_changeset(SelectOptionCellContentChangeset::from_insert("123").to_str(), None) .unwrap(); - assert_eq!( - type_option - .decode_cell_data(cell_data, &field_meta.field_type, &field_meta) - .unwrap() - .content, - "", - ); + + assert_single_select_options(cell_data, &type_option, &field_meta, vec![]); // Invalid changeset assert!(type_option.apply_changeset("123", None).is_err()); @@ -592,49 +576,64 @@ mod tests { let option_ids = vec![google_option.id.clone(), facebook_option.id.clone()].join(SELECTION_IDS_SEPARATOR); let data = SelectOptionCellContentChangeset::from_insert(&option_ids).to_str(); let cell_data = type_option.apply_changeset(data, None).unwrap(); - assert_eq!( - type_option - .decode_cell_data(cell_data, &field_meta.field_type, &field_meta) - .unwrap() - .content, - vec![google_option.name.clone(), facebook_option.name].join(SELECTION_IDS_SEPARATOR), + assert_multi_select_options( + cell_data, + &type_option, + &field_meta, + vec![google_option.clone(), facebook_option.clone()], ); let data = SelectOptionCellContentChangeset::from_insert(&google_option.id).to_str(); let cell_data = type_option.apply_changeset(data, None).unwrap(); - assert_eq!( - type_option - .decode_cell_data(cell_data, &field_meta.field_type, &field_meta) - .unwrap() - .content, - google_option.name, - ); + assert_multi_select_options(cell_data, &type_option, &field_meta, vec![google_option.clone()]); // Invalid option id let cell_data = type_option .apply_changeset(SelectOptionCellContentChangeset::from_insert("").to_str(), None) .unwrap(); - assert_eq!( - type_option - .decode_cell_data(cell_data, &field_meta.field_type, &field_meta) - .unwrap() - .content, - "", - ); + assert_multi_select_options(cell_data, &type_option, &field_meta, vec![]); // Invalid option id let cell_data = type_option .apply_changeset(SelectOptionCellContentChangeset::from_insert("123,456").to_str(), None) .unwrap(); - assert_eq!( - type_option - .decode_cell_data(cell_data, &field_meta.field_type, &field_meta) - .unwrap() - .content, - "", - ); + assert_multi_select_options(cell_data, &type_option, &field_meta, vec![]); // Invalid changeset assert!(type_option.apply_changeset("123", None).is_err()); } + + fn assert_multi_select_options( + cell_data: String, + type_option: &MultiSelectTypeOption, + field_meta: &FieldMeta, + expected: Vec, + ) { + assert_eq!( + expected, + type_option + .decode_cell_data(cell_data, &field_meta.field_type, &field_meta) + .unwrap() + .parse::() + .unwrap() + .select_options, + ); + } + + fn assert_single_select_options( + cell_data: String, + type_option: &SingleSelectTypeOption, + field_meta: &FieldMeta, + expected: Vec, + ) { + assert_eq!( + expected, + type_option + .decode_cell_data(cell_data, &field_meta.field_type, &field_meta) + .unwrap() + .parse::() + .unwrap() + .select_options, + ); + } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index 199ddf38de..3acdfd97c5 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -49,7 +49,7 @@ impl CellDataOperation for RichTextTypeOption { decode_cell_data(encoded_data, decoded_field_type, decoded_field_type, field_meta) } else { let cell_data = encoded_data.into(); - Ok(DecodedCellData::from_content(cell_data)) + Ok(DecodedCellData::new(cell_data)) } } @@ -85,22 +85,26 @@ mod tests { type_option .decode_cell_data(json, &field_type, &date_time_field_meta) .unwrap() - .content, + .parse::() + .unwrap() + .date, "Mar 14,2022".to_owned() ); // Single select let done_option = SelectOption::new("Done"); let done_option_id = done_option.id.clone(); - let single_select = SingleSelectTypeOptionBuilder::default().option(done_option); + let single_select = SingleSelectTypeOptionBuilder::default().option(done_option.clone()); let single_select_field_meta = FieldBuilder::new(single_select).build(); assert_eq!( type_option .decode_cell_data(done_option_id, &FieldType::SingleSelect, &single_select_field_meta) .unwrap() - .content, - "Done".to_owned() + .parse::() + .unwrap() + .select_options, + vec![done_option], ); // Multiple select @@ -109,8 +113,8 @@ mod tests { let ids = vec![google_option.id.clone(), facebook_option.id.clone()].join(SELECTION_IDS_SEPARATOR); let cell_data_changeset = SelectOptionCellContentChangeset::from_insert(&ids).to_str(); let multi_select = MultiSelectTypeOptionBuilder::default() - .option(google_option) - .option(facebook_option); + .option(google_option.clone()) + .option(facebook_option.clone()); let multi_select_field_meta = FieldBuilder::new(multi_select).build(); let multi_type_option = MultiSelectTypeOption::from(&multi_select_field_meta); let cell_data = multi_type_option.apply_changeset(cell_data_changeset, None).unwrap(); @@ -118,8 +122,10 @@ mod tests { type_option .decode_cell_data(cell_data, &FieldType::MultiSelect, &multi_select_field_meta) .unwrap() - .content, - "Google,Facebook".to_owned() + .parse::() + .unwrap() + .select_options, + vec![google_option, facebook_option] ); //Number @@ -129,7 +135,7 @@ mod tests { type_option .decode_cell_data("18443".to_owned(), &FieldType::Number, &number_field_meta) .unwrap() - .content, + .to_string(), "$18,443".to_owned() ); } 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 c161e191c4..e4cee15a6e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,9 +1,9 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::entities::CellIdentifier; use crate::manager::GridUser; -use crate::services::block_meta_manager::GridBlockMetaEditorManager; +use crate::services::block_meta_manager::GridBlockManager; use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder}; -use crate::services::persistence::block_index::BlockIndexPersistence; +use crate::services::persistence::block_index::BlockIndexCache; use crate::services::row::*; use bytes::Bytes; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; @@ -19,20 +19,26 @@ use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; -pub struct ClientGridEditor { +pub struct GridMetaEditor { grid_id: String, user: Arc, grid_pad: Arc>, rev_manager: Arc, - block_meta_manager: Arc, + block_manager: Arc, } -impl ClientGridEditor { +impl Drop for GridMetaEditor { + fn drop(&mut self) { + tracing::trace!("Drop GridMetaEditor"); + } +} + +impl GridMetaEditor { pub async fn new( grid_id: &str, user: Arc, mut rev_manager: RevisionManager, - persistence: Arc, + persistence: Arc, ) -> FlowyResult> { let token = user.token()?; let cloud = Arc::new(GridRevisionCloudService { token }); @@ -41,13 +47,13 @@ impl ClientGridEditor { let grid_pad = Arc::new(RwLock::new(grid_pad)); let blocks = grid_pad.read().await.get_block_metas(); - let block_meta_manager = Arc::new(GridBlockMetaEditorManager::new(grid_id, &user, blocks, persistence).await?); + let block_meta_manager = Arc::new(GridBlockManager::new(grid_id, &user, blocks, persistence).await?); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), user, grid_pad, rev_manager, - block_meta_manager, + block_manager: block_meta_manager, })) } @@ -254,10 +260,7 @@ impl ClientGridEditor { let row_order = RowOrder::from(&row_meta); // insert the row - let row_count = self - .block_meta_manager - .create_row(&block_id, row_meta, start_row_id) - .await?; + let row_count = self.block_manager.create_row(&block_id, row_meta, start_row_id).await?; // update block row count let changeset = GridBlockMetaChangeset::from_row_count(&block_id, row_count); @@ -277,7 +280,7 @@ impl ClientGridEditor { .or_insert_with(Vec::new) .push(row_meta); } - let changesets = self.block_meta_manager.insert_row(rows_by_block_id).await?; + let changesets = self.block_manager.insert_row(rows_by_block_id).await?; for changeset in changesets { let _ = self.update_block(changeset).await?; } @@ -286,7 +289,7 @@ impl ClientGridEditor { pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { let field_metas = self.get_field_metas::(None).await?; - self.block_meta_manager + self.block_manager .update_row(changeset, |row_meta| make_row_from_row_meta(&field_metas, row_meta)) .await } @@ -309,7 +312,7 @@ impl ClientGridEditor { } pub async fn get_row(&self, row_id: &str) -> FlowyResult> { - match self.block_meta_manager.get_row_meta(row_id).await? { + match self.block_manager.get_row_meta(row_id).await? { None => Ok(None), Some(row_meta) => { let field_metas = self.get_field_metas::(None).await?; @@ -321,7 +324,7 @@ impl ClientGridEditor { } } pub async fn delete_row(&self, row_id: &str) -> FlowyResult<()> { - let _ = self.block_meta_manager.delete_row(row_id).await?; + let _ = self.block_manager.delete_row(row_id).await?; Ok(()) } @@ -331,12 +334,12 @@ impl ClientGridEditor { pub async fn get_cell(&self, params: &CellIdentifier) -> Option { let field_meta = self.get_field_meta(¶ms.field_id).await?; - let row_meta = self.block_meta_manager.get_row_meta(¶ms.row_id).await.ok()??; + let row_meta = self.block_manager.get_row_meta(¶ms.row_id).await.ok()??; make_cell(¶ms.field_id, &field_meta, &row_meta) } pub async fn get_cell_meta(&self, row_id: &str, field_id: &str) -> FlowyResult> { - let row_meta = self.block_meta_manager.get_row_meta(row_id).await?; + let row_meta = self.block_manager.get_row_meta(row_id).await?; match row_meta { None => Ok(None), Some(row_meta) => { @@ -382,7 +385,7 @@ impl ClientGridEditor { cell_content_changeset, }; let _ = self - .block_meta_manager + .block_manager .update_cell(cell_changeset, |row_meta| { make_row_from_row_meta(&field_metas, row_meta) }) @@ -403,7 +406,7 @@ impl ClientGridEditor { } pub async fn delete_rows(&self, row_orders: Vec) -> FlowyResult<()> { - let changesets = self.block_meta_manager.delete_rows(row_orders).await?; + let changesets = self.block_manager.delete_rows(row_orders).await?; for changeset in changesets { let _ = self.update_block(changeset).await?; } @@ -415,7 +418,7 @@ impl ClientGridEditor { let field_orders = pad_read_guard.get_field_orders(); let mut block_orders = vec![]; for block_order in pad_read_guard.get_block_metas() { - let row_orders = self.block_meta_manager.get_row_orders(&block_order.block_id).await?; + let row_orders = self.block_manager.get_row_orders(&block_order.block_id).await?; let block_order = GridBlockOrder { block_id: block_order.block_id, row_orders, @@ -442,7 +445,7 @@ impl ClientGridEditor { .collect::>(), Some(block_ids) => block_ids, }; - let snapshots = self.block_meta_manager.make_block_snapshots(block_ids).await?; + let snapshots = self.block_manager.make_block_snapshots(block_ids).await?; Ok(snapshots) } @@ -476,10 +479,7 @@ impl ClientGridEditor { } pub async fn move_row(&self, row_id: &str, from: i32, to: i32) -> FlowyResult<()> { - let _ = self - .block_meta_manager - .move_row(row_id, from as usize, to as usize) - .await?; + let _ = self.block_manager.move_row(row_id, from as usize, to as usize).await?; Ok(()) } @@ -565,7 +565,7 @@ impl ClientGridEditor { } #[cfg(feature = "flowy_unit_test")] -impl ClientGridEditor { +impl GridMetaEditor { pub fn rev_manager(&self) -> Arc { self.rev_manager.clone() } diff --git a/frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs b/frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs index df75ec629c..c62dc502ad 100644 --- a/frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs +++ b/frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs @@ -7,11 +7,11 @@ use flowy_database::{ use flowy_error::FlowyResult; use std::sync::Arc; -pub struct BlockIndexPersistence { +pub struct BlockIndexCache { database: Arc, } -impl BlockIndexPersistence { +impl BlockIndexCache { pub fn new(database: Arc) -> Self { Self { database } } @@ -26,7 +26,7 @@ impl BlockIndexPersistence { Ok(block_id) } - pub fn insert_or_update(&self, block_id: &str, row_id: &str) -> FlowyResult<()> { + pub fn insert(&self, block_id: &str, row_id: &str) -> FlowyResult<()> { let conn = self.database.db_connection()?; let item = IndexItem { row_id: row_id.to_string(), diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs index 28fc0527a1..3191fa2cc0 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs @@ -1,5 +1,6 @@ use crate::services::field::*; -use flowy_error::{ErrorCode, FlowyError, FlowyResult}; +use bytes::Bytes; +use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; use std::fmt::Formatter; @@ -146,8 +147,15 @@ pub fn decode_cell_data_from_type_option_cell_data DecodedCellData { if let Ok(type_option_cell_data) = data.try_into() { let (encoded_data, s_field_type) = type_option_cell_data.split(); - decode_cell_data(encoded_data, &s_field_type, field_type, field_meta).unwrap_or_default() + match decode_cell_data(encoded_data, &s_field_type, field_type, field_meta) { + Ok(cell_data) => cell_data, + Err(e) => { + tracing::error!("Decode cell data failed, {:?}", e); + DecodedCellData::default() + } + } } else { + tracing::error!("Decode type option data failed"); DecodedCellData::default() } } @@ -159,6 +167,7 @@ pub fn decode_cell_data>( field_meta: &FieldMeta, ) -> FlowyResult { let encoded_data = encoded_data.into(); + tracing::info!("😁{:?}", field_meta.type_options); let get_cell_data = || { let data = match t_field_type { FieldType::RichText => field_meta @@ -187,13 +196,7 @@ pub fn decode_cell_data>( }; match get_cell_data() { - Some(Ok(data)) => { - tracing::Span::current().record( - "content", - &format!("{:?}: {}", field_meta.field_type, data.content).as_str(), - ); - Ok(data) - } + Some(Ok(data)) => Ok(data), Some(Err(err)) => { tracing::error!("{:?}", err); Ok(DecodedCellData::default()) @@ -230,23 +233,40 @@ where #[derive(Default)] pub struct DecodedCellData { - raw: String, - pub content: String, + pub data: Vec, } impl DecodedCellData { - pub fn from_content(content: String) -> Self { + pub fn new>(data: T) -> Self { Self { - raw: content.clone(), - content, + data: data.as_ref().to_vec(), } } - pub fn new(raw: String, content: String) -> Self { - Self { raw, content } + pub fn try_from_bytes>(bytes: T) -> FlowyResult + where + >::Error: std::fmt::Debug, + { + let bytes = bytes.try_into().map_err(internal_error)?; + Ok(Self { data: bytes.to_vec() }) } - pub fn split(self) -> (String, String) { - (self.raw, self.content) + pub fn parse<'a, T: TryFrom<&'a [u8]>>(&'a self) -> FlowyResult + where + >::Error: std::fmt::Debug, + { + T::try_from(self.data.as_ref()).map_err(internal_error) + } +} + +impl ToString for DecodedCellData { + fn to_string(&self) -> String { + match String::from_utf8(self.data.clone()) { + Ok(s) => s, + Err(e) => { + tracing::error!("DecodedCellData to string failed: {:?}", e); + "".to_string() + } + } } } 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 af4af0e491..865058ffb6 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 @@ -31,17 +31,15 @@ pub fn make_cell_by_field_id( cell_meta: CellMeta, ) -> Option<(String, Cell)> { let field_meta = field_map.get(&field_id)?; - let (raw, content) = - decode_cell_data_from_type_option_cell_data(cell_meta.data, field_meta, &field_meta.field_type).split(); - let cell = Cell::new(&field_id, content, raw); + let data = decode_cell_data_from_type_option_cell_data(cell_meta.data, field_meta, &field_meta.field_type).data; + let cell = Cell::new(&field_id, data); Some((field_id, cell)) } pub fn make_cell(field_id: &str, field_meta: &FieldMeta, row_meta: &RowMeta) -> Option { let cell_meta = row_meta.cells.get(field_id)?.clone(); - let (raw, content) = - decode_cell_data_from_type_option_cell_data(cell_meta.data, field_meta, &field_meta.field_type).split(); - Some(Cell::new(field_id, content, raw)) + let data = decode_cell_data_from_type_option_cell_data(cell_meta.data, field_meta, &field_meta.field_type).data; + Some(Cell::new(field_id, data)) } pub(crate) fn make_row_orders_from_row_metas(row_metas: &[Arc]) -> Vec { diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index b78f9be551..7b210d4f95 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -2,7 +2,7 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; use chrono::NaiveDateTime; use flowy_grid::services::field::{ - DateCellContentChangeset, MultiSelectTypeOption, SelectOption, SelectOptionCellContentChangeset, + DateCellContentChangeset, DateCellData, MultiSelectTypeOption, SelectOption, SelectOptionCellContentChangeset, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR, }; use flowy_grid::services::row::{decode_cell_data_from_type_option_cell_data, CreateRowMetaBuilder}; @@ -295,8 +295,9 @@ async fn grid_row_add_date_cell_test() { let cell_data = context.cell_by_field_id.get(&date_field.id).unwrap().clone(); assert_eq!( decode_cell_data_from_type_option_cell_data(cell_data.data.clone(), &date_field, &date_field.field_type) - .split() - .1, + .parse::() + .unwrap() + .date, "2022/03/16", ); let scripts = vec![CreateRow { context }]; diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 956bd4dd6c..37c3b736d4 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,6 +1,6 @@ use bytes::Bytes; use flowy_grid::services::field::*; -use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; +use flowy_grid::services::grid_editor::{GridMetaEditor, GridPadBuilder}; use flowy_grid::services::row::CreateRowMetaPayload; use flowy_grid_data_model::entities::{ BuildGridContext, CellChangeset, Field, FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta, @@ -72,7 +72,7 @@ pub enum EditorScript { pub struct GridEditorTest { pub sdk: FlowySDKTest, pub grid_id: String, - pub editor: Arc, + pub editor: Arc, pub field_metas: Vec, pub grid_blocks: Vec, pub row_metas: Vec>, @@ -239,7 +239,7 @@ impl GridEditorTest { } } -async fn get_row_metas(editor: &Arc) -> Vec> { +async fn get_row_metas(editor: &Arc) -> Vec> { editor .grid_block_snapshots(None) .await diff --git a/frontend/rust-lib/flowy-text-block/src/editor.rs b/frontend/rust-lib/flowy-text-block/src/editor.rs index d43fc24f1c..c1e50536a5 100644 --- a/frontend/rust-lib/flowy-text-block/src/editor.rs +++ b/frontend/rust-lib/flowy-text-block/src/editor.rs @@ -21,7 +21,7 @@ use lib_ws::WSConnectState; use std::sync::Arc; use tokio::sync::{mpsc, oneshot}; -pub struct ClientTextBlockEditor { +pub struct TextBlockEditor { pub doc_id: String, #[allow(dead_code)] rev_manager: Arc, @@ -30,7 +30,7 @@ pub struct ClientTextBlockEditor { edit_cmd_tx: EditorCommandSender, } -impl ClientTextBlockEditor { +impl TextBlockEditor { #[allow(unused_variables)] pub(crate) async fn new( doc_id: &str, @@ -185,7 +185,7 @@ impl ClientTextBlockEditor { pub(crate) fn receive_ws_state(&self, _state: &WSConnectState) {} } -impl std::ops::Drop for ClientTextBlockEditor { +impl std::ops::Drop for TextBlockEditor { fn drop(&mut self) { tracing::trace!("{} ClientBlockEditor was dropped", self.doc_id) } @@ -204,7 +204,7 @@ fn spawn_edit_queue( } #[cfg(feature = "flowy_unit_test")] -impl ClientTextBlockEditor { +impl TextBlockEditor { pub async fn text_block_delta(&self) -> FlowyResult { let (ret, rx) = oneshot::channel::>(); let msg = EditorCommand::ReadDelta { ret }; diff --git a/frontend/rust-lib/flowy-text-block/src/manager.rs b/frontend/rust-lib/flowy-text-block/src/manager.rs index 8a34c6916d..9325fe6001 100644 --- a/frontend/rust-lib/flowy-text-block/src/manager.rs +++ b/frontend/rust-lib/flowy-text-block/src/manager.rs @@ -1,4 +1,4 @@ -use crate::{editor::ClientTextBlockEditor, errors::FlowyError, BlockCloudService}; +use crate::{editor::TextBlockEditor, errors::FlowyError, BlockCloudService}; use bytes::Bytes; use dashmap::DashMap; use flowy_database::ConnectionPool; @@ -47,8 +47,8 @@ impl TextBlockManager { Ok(()) } - #[tracing::instrument(level = "debug", skip(self, block_id), fields(block_id), err)] - pub async fn open_block>(&self, block_id: T) -> Result, FlowyError> { + #[tracing::instrument(level = "trace", skip(self, block_id), fields(block_id), err)] + pub async fn open_block>(&self, block_id: T) -> Result, FlowyError> { let block_id = block_id.as_ref(); tracing::Span::current().record("block_id", &block_id); self.get_block_editor(block_id).await @@ -108,7 +108,7 @@ impl TextBlockManager { } impl TextBlockManager { - async fn get_block_editor(&self, block_id: &str) -> FlowyResult> { + async fn get_block_editor(&self, block_id: &str) -> FlowyResult> { match self.editor_map.get(block_id) { None => { let db_pool = self.user.db_pool()?; @@ -123,7 +123,7 @@ impl TextBlockManager { &self, block_id: &str, pool: Arc, - ) -> Result, FlowyError> { + ) -> Result, FlowyError> { let user = self.user.clone(); let token = self.user.token()?; let rev_manager = self.make_rev_manager(block_id, pool.clone())?; @@ -132,7 +132,7 @@ impl TextBlockManager { server: self.cloud_service.clone(), }); let doc_editor = - ClientTextBlockEditor::new(block_id, user, rev_manager, self.rev_web_socket.clone(), cloud_service).await?; + TextBlockEditor::new(block_id, user, rev_manager, self.rev_web_socket.clone(), cloud_service).await?; self.editor_map.insert(block_id, &doc_editor); Ok(doc_editor) } @@ -180,7 +180,7 @@ impl RevisionCloudService for TextBlockRevisionCloudService { } pub struct TextBlockEditorMap { - inner: DashMap>, + inner: DashMap>, } impl TextBlockEditorMap { @@ -188,14 +188,14 @@ impl TextBlockEditorMap { Self { inner: DashMap::new() } } - pub(crate) fn insert(&self, block_id: &str, doc: &Arc) { + pub(crate) fn insert(&self, block_id: &str, doc: &Arc) { if self.inner.contains_key(block_id) { log::warn!("Doc:{} already exists in cache", block_id); } self.inner.insert(block_id.to_string(), doc.clone()); } - pub(crate) fn get(&self, block_id: &str) -> Option> { + pub(crate) fn get(&self, block_id: &str) -> Option> { Some(self.inner.get(block_id)?.clone()) } diff --git a/frontend/rust-lib/flowy-text-block/tests/document/script.rs b/frontend/rust-lib/flowy-text-block/tests/document/script.rs index 5511896fc2..1722724c3f 100644 --- a/frontend/rust-lib/flowy-text-block/tests/document/script.rs +++ b/frontend/rust-lib/flowy-text-block/tests/document/script.rs @@ -1,6 +1,6 @@ use flowy_revision::disk::RevisionState; use flowy_test::{helper::ViewTest, FlowySDKTest}; -use flowy_text_block::editor::ClientTextBlockEditor; +use flowy_text_block::editor::TextBlockEditor; use flowy_text_block::TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS; use lib_ot::{core::Interval, rich_text::RichTextDelta}; use std::sync::Arc; @@ -19,7 +19,7 @@ pub enum EditorScript { pub struct TextBlockEditorTest { pub sdk: FlowySDKTest, - pub editor: Arc, + pub editor: Arc, } impl TextBlockEditorTest { diff --git a/frontend/scripts/makefile/tests.toml b/frontend/scripts/makefile/tests.toml index 89e3ea9140..b8082f651b 100644 --- a/frontend/scripts/makefile/tests.toml +++ b/frontend/scripts/makefile/tests.toml @@ -1,30 +1,18 @@ -[tasks.test_local] -category = "Build" -dependencies = ["rm_cache"] -description = "Build desktop targets." +[tasks.rust_unit_test] +run_task = { name = ["rust_lib_unit_test", "shared_lib_unit_test"] } + +[tasks.rust_lib_unit_test] +description = "Run rust-lib unit tests" script = ''' cd rust-lib -cargo test +RUST_LOG=info cargo test --no-default-features --features="sync" ''' +[tasks.shared_lib_unit_test] +description = "Run shared-lib unit test" +script = ''' +cd ../shared-lib +RUST_LOG=info cargo test --no-default-features +''' -[tasks.test_remote] -dependencies = ["rm_cache"] -script = """ -cd rust-lib -cargo test --features "flowy-folder/http_server","flowy-user/http_server" -""" - - -[tasks.run_server] -script = """ -cd backend -cargo run -""" - - -[tasks.rm_cache] -script = """ -rm -rf rust-lib/flowy-test/temp -""" \ No newline at end of file diff --git a/frontend/scripts/makefile/tool.toml b/frontend/scripts/makefile/tool.toml new file mode 100644 index 0000000000..bd0504f6fc --- /dev/null +++ b/frontend/scripts/makefile/tool.toml @@ -0,0 +1,27 @@ +[tasks.rust_clean] +script = [ + """ + cd rust-lib + cargo clean + + cd ../../shared-lib + cargo clean + + rm -rf lib-infra/.cache + """, +] +script_runner = "@shell" + +[tasks.rust_clean.windows] +script = [ + """ + cd rust-lib + cargo clean + + cd ../../shared-lib + cargo clean + + rmdir /s/q "lib-infra/.cache" + """, +] +script_runner = "@duckscript" \ No newline at end of file diff --git a/shared-lib/flowy-derive/src/proto_buf/deserialize.rs b/shared-lib/flowy-derive/src/proto_buf/deserialize.rs index e09f7ea847..f0325db3b0 100644 --- a/shared-lib/flowy-derive/src/proto_buf/deserialize.rs +++ b/shared-lib/flowy-derive/src/proto_buf/deserialize.rs @@ -30,6 +30,14 @@ pub fn make_de_token_steam(ctxt: &Ctxt, ast: &ASTContainer) -> Option for #struct_ident { + type Error = ::protobuf::ProtobufError; + fn try_from(bytes: &[u8]) -> Result { + let pb: crate::protobuf::#pb_ty = ::protobuf::Message::parse_from_bytes(bytes)?; + #struct_ident::try_from(pb) + } + } + impl std::convert::TryFrom for #struct_ident { type Error = ::protobuf::ProtobufError; fn try_from(mut pb: crate::protobuf::#pb_ty) -> Result { 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 e51f2222e2..5889e1093b 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -484,17 +484,13 @@ pub struct Cell { pub field_id: String, #[pb(index = 2)] - pub content: String, - - #[pb(index = 3)] - pub data: String, + pub data: Vec, } impl Cell { - pub fn new(field_id: &str, content: String, data: String) -> Self { + pub fn new(field_id: &str, data: Vec) -> Self { Self { field_id: field_id.to_owned(), - content, data, } } @@ -502,8 +498,7 @@ impl Cell { pub fn empty(field_id: &str) -> Self { Self { field_id: field_id.to_owned(), - content: "".to_string(), - data: "".to_string(), + data: vec![], } } } 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 8c94e1aa30..c087cc5ea3 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 @@ -4743,8 +4743,7 @@ impl ::protobuf::reflect::ProtobufValue for GridBlock { pub struct Cell { // message fields pub field_id: ::std::string::String, - pub content: ::std::string::String, - pub data: ::std::string::String, + pub data: ::std::vec::Vec, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -4787,36 +4786,10 @@ impl Cell { ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) } - // string content = 2; + // bytes data = 2; - pub fn get_content(&self) -> &str { - &self.content - } - pub fn clear_content(&mut self) { - self.content.clear(); - } - - // Param is passed by value, moved - pub fn set_content(&mut self, v: ::std::string::String) { - self.content = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_content(&mut self) -> &mut ::std::string::String { - &mut self.content - } - - // Take field - pub fn take_content(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.content, ::std::string::String::new()) - } - - // string data = 3; - - - pub fn get_data(&self) -> &str { + pub fn get_data(&self) -> &[u8] { &self.data } pub fn clear_data(&mut self) { @@ -4824,19 +4797,19 @@ impl Cell { } // Param is passed by value, moved - pub fn set_data(&mut self, v: ::std::string::String) { + pub fn set_data(&mut self, v: ::std::vec::Vec) { self.data = v; } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_data(&mut self) -> &mut ::std::string::String { + pub fn mut_data(&mut self) -> &mut ::std::vec::Vec { &mut self.data } // Take field - pub fn take_data(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.data, ::std::string::String::new()) + pub fn take_data(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.data, ::std::vec::Vec::new()) } } @@ -4853,10 +4826,7 @@ impl ::protobuf::Message for Cell { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; }, 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.content)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.data)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -4873,11 +4843,8 @@ impl ::protobuf::Message for Cell { if !self.field_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.field_id); } - if !self.content.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.content); - } if !self.data.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.data); + my_size += ::protobuf::rt::bytes_size(2, &self.data); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -4888,11 +4855,8 @@ impl ::protobuf::Message for Cell { if !self.field_id.is_empty() { os.write_string(1, &self.field_id)?; } - if !self.content.is_empty() { - os.write_string(2, &self.content)?; - } if !self.data.is_empty() { - os.write_string(3, &self.data)?; + os.write_bytes(2, &self.data)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -4937,12 +4901,7 @@ impl ::protobuf::Message for Cell { |m: &Cell| { &m.field_id }, |m: &mut Cell| { &mut m.field_id }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "content", - |m: &Cell| { &m.content }, - |m: &mut Cell| { &mut m.content }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( "data", |m: &Cell| { &m.data }, |m: &mut Cell| { &mut m.data }, @@ -4964,7 +4923,6 @@ impl ::protobuf::Message for Cell { impl ::protobuf::Clear for Cell { fn clear(&mut self) { self.field_id.clear(); - self.content.clear(); self.data.clear(); self.unknown_fields.clear(); } @@ -8343,50 +8301,49 @@ static file_descriptor_proto_data: &'static [u8] = b"\ derR\x0bdeletedRows\x123\n\x0cupdated_rows\x18\x04\x20\x03(\x0b2\x10.Upd\ atedRowOrderR\x0bupdatedRows\"E\n\tGridBlock\x12\x0e\n\x02id\x18\x01\x20\ \x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b2\t.RowOrderR\trow\ - Orders\"O\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\ - \x12\x18\n\x07content\x18\x02\x20\x01(\tR\x07content\x12\x12\n\x04data\ - \x18\x03\x20\x01(\tR\x04data\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\ - \x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\ - \n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05va\ - lue\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\x12Ins\ - ertFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\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_fie\ - ld_id\x18\x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_start_fiel\ - d_id\"|\n\x1cUpdateFieldTypeOptionPayload\x12\x17\n\x07grid_id\x18\x01\ - \x20\x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fiel\ - dId\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\"\ - d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gri\ - dId\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\ - \"\xb3\x01\n\rCellChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06\ - gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08fie\ - ld_id\x18\x03\x20\x01(\tR\x07fieldId\x126\n\x16cell_content_changeset\ - \x18\x04\x20\x01(\tH\0R\x14cellContentChangesetB\x1f\n\x1done_of_cell_co\ - ntent_changeset**\n\x0cMoveItemType\x12\r\n\tMoveField\x10\0\x12\x0b\n\ - \x07MoveRow\x10\x01*m\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\ - \x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSele\ - ct\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\ - \x05\x12\x07\n\x03URL\x10\x06b\x06proto3\ + Orders\"5\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\ + \x12\x12\n\x04data\x18\x02\x20\x01(\x0cR\x04data\"+\n\x0cRepeatedCell\ + \x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11Cre\ + ateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06\ + GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlock\ + Id\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayl\ + oad\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(\ + \tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.FieldR\x05fie\ + ld\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\"|\n\x1cUpdateFieldTypeOptionPayload\x12\x17\n\ + \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\ + \x20\x01(\tR\x07fieldId\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\ + \x0etypeOptionData\"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\"\xb3\x01\n\rCellChangeset\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05ro\ + wId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x126\n\x16cell_\ + content_changeset\x18\x04\x20\x01(\tH\0R\x14cellContentChangesetB\x1f\n\ + \x1done_of_cell_content_changeset**\n\x0cMoveItemType\x12\r\n\tMoveField\ + \x10\0\x12\x0b\n\x07MoveRow\x10\x01*m\n\tFieldType\x12\x0c\n\x08RichText\ + \x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\ + \x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08C\ + heckbox\x10\x05\x12\x07\n\x03URL\x10\x06b\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 b19ba4ef82..f06d84e5b8 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 @@ -95,8 +95,7 @@ message GridBlock { } message Cell { string field_id = 1; - string content = 2; - string data = 3; + bytes data = 2; } message RepeatedCell { repeated Cell items = 1; diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs index 3f727faf59..3370719e68 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs @@ -175,7 +175,7 @@ impl GridBlockMetaPad { match cal_diff::(old, new) { None => Ok(None), Some(delta) => { - tracing::debug!("[GridBlockMeta] Composing delta {}", delta.to_delta_str()); + tracing::trace!("[GridBlockMeta] Composing delta {}", delta.to_delta_str()); // tracing::debug!( // "[GridBlockMeta] current delta: {}", // self.delta.to_str().unwrap_or_else(|_| "".to_string())