From 0502eec71785d732b0ec101eac88581c4d970d7e Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 7 Mar 2022 20:51:13 +0800 Subject: [PATCH 01/28] chore: config plugin display --- .../app_flowy/lib/workspace/presentation/home/home_stack.dart | 2 +- .../workspace/presentation/plugins/doc/src/document_page.dart | 3 +-- .../lib/workspace/presentation/plugins/grid/grid.dart | 2 +- .../workspace/presentation/plugins/grid/src/layout/sizes.dart | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/presentation/home/home_stack.dart b/frontend/app_flowy/lib/workspace/presentation/home/home_stack.dart index 8e249ab9c5..65e315f56d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/home_stack.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/home_stack.dart @@ -168,7 +168,7 @@ class HomeStackManager { index: getIt().indexOf(notifier.plugin.ty), children: getIt().supportPluginTypes.map((pluginType) { if (pluginType == notifier.plugin.ty) { - return notifier.plugin.display.buildWidget(); + return notifier.plugin.display.buildWidget().padding(horizontal: 40, vertical: 28); } else { return const BlankPage(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/document_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/document_page.dart index 30b88e652f..031edb93fd 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/document_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/src/document_page.dart @@ -10,7 +10,6 @@ import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; -import 'package:styled_widget/styled_widget.dart'; import 'styles.dart'; import 'widget/banner.dart'; @@ -82,7 +81,7 @@ class _DocumentPageState extends State { _renderToolbar(controller), const VSpace(10), ], - ).padding(horizontal: 40, top: 28), + ), ), ], ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart index cf6b4c9032..b73970508c 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart @@ -28,7 +28,7 @@ class GridPluginBuilder implements PluginBuilder { class GridPluginConfig implements PluginConfig { @override - bool get creatable => false; + bool get creatable => true; } class GridPlugin extends Plugin { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart index e833df5cc4..13f7200ceb 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart @@ -10,7 +10,7 @@ class GridSize { static double get scrollBarSize => 12 * scale; static double get headerHeight => 50 * scale; - static double get rowHeight => 50 * scale; + static double get rowHeight => 36 * scale; static double get footerHeight => 40 * scale; static double get firstHeaderPadding => 20 * scale; } From 54cf4518266116bdf05af457ff2b2d28853a4d30 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 8 Mar 2022 15:25:56 +0800 Subject: [PATCH 02/28] feat: config textfield cell --- .../lib/startup/home_deps_resolver.dart | 37 ++-- .../workspace/application/app/prelude.dart | 3 + .../workspace/application/doc/prelude.dart | 4 + .../lib/workspace/application/grid/data.dart | 35 ++++ .../workspace/application/grid/grid_bloc.dart | 36 +--- .../workspace/application/grid/prelude.dart | 5 + .../workspace/application/grid/row_bloc.dart | 50 ++++++ .../application/grid/row_service.dart | 10 ++ .../workspace/application/home/prelude.dart | 1 + .../workspace/application/menu/prelude.dart | 2 + .../workspace/application/trash/prelude.dart | 3 + .../workspace/application/view/prelude.dart | 3 + .../application/workspace/prelude.dart | 3 + .../home/menu/app/header/header.dart | 4 +- .../plugins/grid/src/grid_page.dart | 12 +- .../plugins/grid/src/layout/layout.dart | 2 +- .../plugins/grid/src/layout/sizes.dart | 7 +- .../src/widgets/content/cell_builder.dart | 2 +- .../src/widgets/content/cell_container.dart | 30 ++-- .../grid/src/widgets/content/grid_cell.dart | 92 +++++++--- .../grid/src/widgets/content/grid_row.dart | 86 +++++----- .../grid/src/widgets/footer/grid_footer.dart | 2 +- .../grid/src/widgets/header/header_cell.dart | 2 +- .../flowy-grid-data-model/grid.pb.dart | 42 +++++ .../flowy-grid-data-model/grid.pbjson.dart | 9 +- frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- .../flowy-grid/src/services/grid_builder.rs | 28 +-- .../flowy-grid/src/services/grid_editor.rs | 12 +- .../src/entities/grid.rs | 49 +++++- .../src/protobuf/model/grid.rs | 161 +++++++++++++++--- .../src/protobuf/proto/grid.proto | 3 + 31 files changed, 517 insertions(+), 222 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/app/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/doc/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/data.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/row_service.dart create mode 100644 frontend/app_flowy/lib/workspace/application/home/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/menu/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/trash/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/view/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/workspace/prelude.dart diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index f8c8d60e8f..9a2a47301e 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -1,26 +1,14 @@ import 'package:app_flowy/user/application/user_listener.dart'; import 'package:app_flowy/user/application/user_service.dart'; -import 'package:app_flowy/workspace/application/app/app_bloc.dart'; -import 'package:app_flowy/workspace/application/app/app_listener.dart'; -import 'package:app_flowy/workspace/application/app/app_service.dart'; -import 'package:app_flowy/workspace/application/doc/doc_bloc.dart'; -import 'package:app_flowy/workspace/application/doc/doc_service.dart'; -import 'package:app_flowy/workspace/application/doc/share_bloc.dart'; -import 'package:app_flowy/workspace/application/doc/share_service.dart'; -import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; -import 'package:app_flowy/workspace/application/grid/grid_service.dart'; -import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart'; -import 'package:app_flowy/workspace/application/menu/menu_bloc.dart'; -import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart'; -import 'package:app_flowy/workspace/application/trash/trash_bloc.dart'; -import 'package:app_flowy/workspace/application/trash/trash_listener.dart'; -import 'package:app_flowy/workspace/application/trash/trash_service.dart'; -import 'package:app_flowy/workspace/application/view/view_bloc.dart'; -import 'package:app_flowy/workspace/application/view/view_listener.dart'; -import 'package:app_flowy/workspace/application/view/view_service.dart'; -import 'package:app_flowy/workspace/application/workspace/welcome_bloc.dart'; -import 'package:app_flowy/workspace/application/workspace/workspace_listener.dart'; -import 'package:app_flowy/workspace/application/workspace/workspace_service.dart'; +import 'package:app_flowy/workspace/application/app/prelude.dart'; +import 'package:app_flowy/workspace/application/doc/prelude.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/application/trash/prelude.dart'; +import 'package:app_flowy/workspace/application/workspace/prelude.dart'; +import 'package:app_flowy/workspace/application/view/prelude.dart'; +import 'package:app_flowy/workspace/application/home/prelude.dart'; +import 'package:app_flowy/workspace/application/menu/prelude.dart'; + import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; @@ -107,6 +95,13 @@ class HomeDepsResolver { ), ); + getIt.registerFactoryParam( + (data, _) => RowBloc( + data: data, + service: RowService(), + ), + ); + // trash getIt.registerLazySingleton(() => TrashService()); getIt.registerLazySingleton(() => TrashListener()); diff --git a/frontend/app_flowy/lib/workspace/application/app/prelude.dart b/frontend/app_flowy/lib/workspace/application/app/prelude.dart new file mode 100644 index 0000000000..f8477049d3 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/app/prelude.dart @@ -0,0 +1,3 @@ +export 'app_bloc.dart'; +export 'app_listener.dart'; +export 'app_service.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/doc/prelude.dart b/frontend/app_flowy/lib/workspace/application/doc/prelude.dart new file mode 100644 index 0000000000..f2befe4cf0 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/doc/prelude.dart @@ -0,0 +1,4 @@ +export 'doc_bloc.dart'; +export 'doc_service.dart'; +export 'share_bloc.dart'; +export 'share_service.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart new file mode 100644 index 0000000000..6c815b7f35 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -0,0 +1,35 @@ +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; + +class GridInfo { + List rows; + List fields; + + GridInfo({ + required this.rows, + required this.fields, + }); + + GridRowData rowAtIndex(int index) { + final row = rows[index]; + return GridRowData( + row: row, + fields: fields, + cellMap: row.cellByFieldId, + ); + } + + int numberOfRows() { + return rows.length; + } +} + +class GridRowData { + Row row; + List fields; + Map cellMap; + GridRowData({ + required this.row, + required this.fields, + required this.cellMap, + }); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart index b915435343..500db75bf3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -7,6 +7,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; +import 'data.dart'; import 'grid_service.dart'; part 'grid_bloc.freezed.dart'; @@ -21,7 +22,7 @@ class GridBloc extends Bloc { on( (event, emit) async { await event.map( - initial: (Initial value) async { + initial: (InitialGrid value) async { await _loadGrid(emit); await _loadFields(emit); await _loadGridInfo(emit); @@ -88,7 +89,7 @@ class GridBloc extends Bloc { @freezed abstract class GridEvent with _$GridEvent { - const factory GridEvent.initial() = Initial; + const factory GridEvent.initial() = InitialGrid; const factory GridEvent.rename(String gridId, String name) = _Rename; const factory GridEvent.updateDesc(String gridId, String desc) = _Desc; const factory GridEvent.delete(String gridId) = _Delete; @@ -113,34 +114,3 @@ class GridLoadingState with _$GridLoadingState { const factory GridLoadingState.loading() = _Loading; const factory GridLoadingState.finish(Either successOrFail) = _Finish; } - -class GridInfo { - List rows; - List fields; - - GridInfo({ - required this.rows, - required this.fields, - }); - - RowInfo rowInfoAtIndex(int index) { - final row = rows[index]; - return RowInfo( - fields: fields, - cellMap: row.cellByFieldId, - ); - } - - int numberOfRows() { - return rows.length; - } -} - -class RowInfo { - List fields; - Map cellMap; - RowInfo({ - required this.fields, - required this.cellMap, - }); -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart new file mode 100644 index 0000000000..bf48b7cc8b --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -0,0 +1,5 @@ +export 'grid_bloc.dart'; +export 'row_bloc.dart'; +export 'row_service.dart'; +export 'grid_service.dart'; +export 'data.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart new file mode 100644 index 0000000000..8feb26e4c7 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart @@ -0,0 +1,50 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:dartz/dartz.dart'; +import 'dart:async'; +import 'data.dart'; +import 'row_service.dart'; + +part 'row_bloc.freezed.dart'; + +class RowBloc extends Bloc { + final RowService service; + final GridRowData data; + + RowBloc({required this.data, required this.service}) : super(RowState.initial()) { + on( + (event, emit) async { + await event.map( + initial: (_InitialRow value) async {}, + createRow: (_CreateRow value) {}, + highlightRow: (_HighlightRow value) { + emit(state.copyWith( + isHighlight: value.rowId.fold(() => false, (rowId) => rowId == data.row.id), + )); + }, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +abstract class RowEvent with _$RowEvent { + const factory RowEvent.initial() = _InitialRow; + const factory RowEvent.createRow() = _CreateRow; + const factory RowEvent.highlightRow(Option rowId) = _HighlightRow; +} + +@freezed +abstract class RowState with _$RowState { + const factory RowState({ + required bool isHighlight, + }) = _RowState; + + factory RowState.initial() => const RowState(isHighlight: false); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart new file mode 100644 index 0000000000..ad04b0add2 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart @@ -0,0 +1,10 @@ +import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; + +class RowService { + Future> createRow({required String gridId}) { + return GridEventCreateRow(GridId(value: gridId)).send(); + } +} diff --git a/frontend/app_flowy/lib/workspace/application/home/prelude.dart b/frontend/app_flowy/lib/workspace/application/home/prelude.dart new file mode 100644 index 0000000000..8d1173c2d6 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/home/prelude.dart @@ -0,0 +1 @@ +export 'home_listen_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/menu/prelude.dart b/frontend/app_flowy/lib/workspace/application/menu/prelude.dart new file mode 100644 index 0000000000..0bf94ea60b --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/menu/prelude.dart @@ -0,0 +1,2 @@ +export 'menu_bloc.dart'; +export 'menu_user_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/trash/prelude.dart b/frontend/app_flowy/lib/workspace/application/trash/prelude.dart new file mode 100644 index 0000000000..5a638a58d1 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/trash/prelude.dart @@ -0,0 +1,3 @@ +export 'trash_bloc.dart'; +export 'trash_listener.dart'; +export 'trash_service.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/view/prelude.dart b/frontend/app_flowy/lib/workspace/application/view/prelude.dart new file mode 100644 index 0000000000..f789b90fcd --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/view/prelude.dart @@ -0,0 +1,3 @@ +export 'view_bloc.dart'; +export 'view_listener.dart'; +export 'view_service.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/workspace/prelude.dart b/frontend/app_flowy/lib/workspace/application/workspace/prelude.dart new file mode 100644 index 0000000000..129462beb0 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/workspace/prelude.dart @@ -0,0 +1,3 @@ +export 'welcome_bloc.dart'; +export 'workspace_listener.dart'; +export 'workspace_service.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart index 58ebabc0c2..da20eafc7b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart @@ -37,7 +37,7 @@ class MenuAppHeader extends StatelessWidget { _renderExpandedIcon(context, theme), // HSpace(MenuAppSizes.iconPadding), _renderTitle(context, theme), - _renderAddButton(context), + _renderCreateViewButton(context), ], ), ); @@ -99,7 +99,7 @@ class MenuAppHeader extends StatelessWidget { ); } - Widget _renderAddButton(BuildContext context) { + Widget _renderCreateViewButton(BuildContext context) { return Tooltip( message: LocaleKeys.menuAppHeader_addPageTooltip.tr(), child: AddButton( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index e53a2f01e2..ae3934b7cb 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -1,4 +1,5 @@ import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/data.dart'; import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart'; @@ -135,10 +136,13 @@ class _GridBodyState extends State { Widget _buildRows(GridInfo gridInfo) { return SliverList( - delegate: SliverChildBuilderDelegate((context, index) { - final rowInfo = gridInfo.rowInfoAtIndex(index); - return RepaintBoundary(child: GridRowWidget(rowInfo)); - }, childCount: gridInfo.numberOfRows()), + delegate: SliverChildBuilderDelegate( + (context, index) { + final data = gridInfo.rowAtIndex(index); + return RepaintBoundary(child: GridRowWidget(data)); + }, + childCount: gridInfo.numberOfRows(), + ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart index a44ad20d39..5b58d3c1c5 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart @@ -8,6 +8,6 @@ class GridLayout { final fieldsWidth = fields.map((field) => field.width.toDouble()).reduce((value, element) => value + element); - return fieldsWidth + GridSize.firstHeaderPadding; + return fieldsWidth + GridSize.startHeaderPadding; } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart index 13f7200ceb..e577311200 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart @@ -1,8 +1,8 @@ class GridInsets { static double scale = 1; - static double get horizontal => 6 * scale; - static double get vertical => 6 * scale; + static double get horizontal => 8 * scale; + static double get vertical => 8 * scale; } class GridSize { @@ -10,7 +10,6 @@ class GridSize { static double get scrollBarSize => 12 * scale; static double get headerHeight => 50 * scale; - static double get rowHeight => 36 * scale; static double get footerHeight => 40 * scale; - static double get firstHeaderPadding => 20 * scale; + static double get startHeaderPadding => 30 * scale; } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index 1c02664c86..efe5a0bd3e 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -4,7 +4,7 @@ import 'grid_cell.dart'; class GridCellBuilder { static GridCellWidget buildCell(Field? field, Cell? cell) { if (field == null || cell == null) { - return const BlankCell(); + return GridTextCell("123123123"); } switch (field.fieldType) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart index edd0de5076..03f0e82115 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart @@ -1,32 +1,26 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; import 'package:flutter/material.dart'; -import 'cell_decoration.dart'; -import 'grid_cell.dart'; class CellContainer extends StatelessWidget { - final GridCellWidget child; + final Widget child; final double width; - const CellContainer({Key? key, required this.child, required this.width}) : super(key: key); + const CellContainer({ + Key? key, + required this.child, + required this.width, + }) : super(key: key); @override Widget build(BuildContext context) { return GestureDetector( behavior: HitTestBehavior.translucent, - onTap: () { - // context - // .read() - // .add(HomeEvent.setEditPannel(CellEditPannelContext())); - }, - child: MouseHoverBuilder( - builder: (_, isHovered) => Container( - width: width, - decoration: CellDecoration.box( - color: isHovered ? Colors.red.withOpacity(.1) : Colors.transparent, - ), - padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), - child: child, + onTap: () {}, + child: Container( + constraints: BoxConstraints( + maxWidth: width, ), + padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), + child: Center(child: IntrinsicHeight(child: child)), ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart index 00e6fad6af..5c0dbabfea 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart @@ -1,6 +1,12 @@ +import 'package:app_flowy/workspace/application/grid/row_bloc.dart'; +import 'package:app_flowy/workspace/presentation/home/menu/app/header/add_button.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'cell_decoration.dart'; // ignore: import_of_legacy_library_into_null_safe @@ -13,12 +19,25 @@ abstract class GridCellWidget extends StatelessWidget { } class GridTextCell extends GridCellWidget { - final String content; - const GridTextCell(this.content, {Key? key}) : super(key: key); + late final TextEditingController _controller; + + GridTextCell(String content, {Key? key}) : super(key: key) { + _controller = TextEditingController(text: content); + } @override Widget build(BuildContext context) { - return Text(content); + return TextField( + controller: _controller, + onChanged: (value) {}, + maxLines: 1, + style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), + decoration: const InputDecoration( + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + isDense: true, + ), + ); } } @@ -72,29 +91,64 @@ class BlankCell extends GridCellWidget { } class RowLeading extends StatelessWidget { - const RowLeading({Key? key}) : super(key: key); + final String rowId; + const RowLeading({required this.rowId, Key? key}) : super(key: key); @override Widget build(BuildContext context) { - // return Expanded( - // child: Container( - // color: Colors.white10, - // width: GridSize.firstHeaderPadding, + return BlocBuilder( + builder: (context, state) { + if (state.isHighlight) { + return Row( + children: const [ + CreateRowButton(), + ], + ); + } + + return const Spacer(); + }, + ); + + // return GestureDetector( + // behavior: HitTestBehavior.translucent, + // onTap: () {}, + // child: MouseHoverBuilder( + // builder: (_, isHovered) => Container( + // width: GridSize.startHeaderPadding, + // decoration: CellDecoration.box( + // color: isHovered ? Colors.red.withOpacity(.1) : Colors.white, + // ), + // padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), + // ), // ), // ); + } +} - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () {}, - child: MouseHoverBuilder( - builder: (_, isHovered) => Container( - width: GridSize.firstHeaderPadding, - decoration: CellDecoration.box( - color: isHovered ? Colors.red.withOpacity(.1) : Colors.white, - ), - padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), - ), +class CreateRowButton extends StatelessWidget { + const CreateRowButton({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return Tooltip( + message: '', + child: FlowyIconButton( + hoverColor: theme.hover, + width: 22, + onPressed: () => context.read().add(const RowEvent.createRow()), + icon: svg("home/add"), ), ); } } + +class DrawRowButton extends StatelessWidget { + const DrawRowButton({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index 4d5da03423..c251546cce 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -1,62 +1,56 @@ -import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'cell_builder.dart'; import 'cell_container.dart'; import 'grid_cell.dart'; - -class GridRowContext { - final RepeatedFieldOrder fieldOrders; - final Map fieldById; - final Map cellByFieldId; - GridRowContext(this.fieldOrders, this.fieldById, this.cellByFieldId); -} +import 'package:dartz/dartz.dart'; class GridRowWidget extends StatelessWidget { - final RowInfo rowInfo; + final GridRowData data; final Function(bool)? onHoverChange; - const GridRowWidget(this.rowInfo, {Key? key, this.onHoverChange}) : super(key: key); + const GridRowWidget(this.data, {Key? key, this.onHoverChange}) : super(key: key); @override Widget build(BuildContext context) { - return SizedBox( - height: GridSize.rowHeight, - child: _buildRowBody(), + return BlocProvider( + create: (context) => getIt(param1: data), + child: BlocBuilder( + builder: (context, state) { + return GestureDetector( + behavior: HitTestBehavior.translucent, + child: MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (p) => context.read().add(RowEvent.highlightRow(some(data.row.id))), + onExit: (p) => context.read().add(RowEvent.highlightRow(none())), + child: SizedBox( + height: data.row.height.toDouble(), + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: _buildCells(), + ), + ), + ), + ); + }, + ), ); } - Widget _buildRowBody() { - Widget rowWidget = Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: _buildCells(), - ); - - if (onHoverChange != null) { - rowWidget = MouseRegion( - onEnter: (event) => onHoverChange!(true), - onExit: (event) => onHoverChange!(false), - cursor: MouseCursor.uncontrolled, - child: rowWidget, - ); - } - - return rowWidget; - } - List _buildCells() { - var cells = List.empty(growable: true); - cells.add(const RowLeading()); - - for (var field in rowInfo.fields) { - final data = rowInfo.cellMap[field.id]; - final cell = CellContainer( - width: field.width.toDouble(), - child: GridCellBuilder.buildCell(field, data), - ); - - cells.add(cell); - } - return cells; + return [ + RowLeading(rowId: data.row.id), + ...data.fields.map( + (field) { + final cellData = data.cellMap[field.id]; + return CellContainer( + width: field.width.toDouble(), + child: GridCellBuilder.buildCell(field, cellData), + ); + }, + ) + ].toList(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart index cdbb0d6e51..6e1befe18e 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart @@ -34,7 +34,7 @@ class AddRowButton extends StatelessWidget { onTap: onTap, child: MouseHoverBuilder( builder: (_, isHovered) => Container( - width: GridSize.firstHeaderPadding, + width: GridSize.startHeaderPadding, height: GridSize.footerHeight, decoration: CellDecoration.box( color: isHovered ? Colors.red.withOpacity(.1) : Colors.white, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index 4148f1e041..ca59069f3f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -45,7 +45,7 @@ class HeaderCellLeading extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - width: GridSize.firstHeaderPadding, + width: GridSize.startHeaderPadding, color: GridHeaderConstants.backgroundColor, ); } 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 102be7fb09..6fd298b16d 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 @@ -550,6 +550,7 @@ class RawRow extends $pb.GeneratedMessage { ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..m<$core.String, RawCell>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'RawRow.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: RawCell.create) + ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) ..hasRequiredFields = false ; @@ -558,6 +559,7 @@ class RawRow extends $pb.GeneratedMessage { $core.String? id, $core.String? gridId, $core.Map<$core.String, RawCell>? cellByFieldId, + $core.int? height, }) { final _result = create(); if (id != null) { @@ -569,6 +571,9 @@ class RawRow extends $pb.GeneratedMessage { if (cellByFieldId != null) { _result.cellByFieldId.addAll(cellByFieldId); } + if (height != null) { + _result.height = height; + } return _result; } factory RawRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -612,6 +617,15 @@ class RawRow extends $pb.GeneratedMessage { @$pb.TagNumber(3) $core.Map<$core.String, RawCell> get cellByFieldId => $_getMap(2); + + @$pb.TagNumber(4) + $core.int get height => $_getIZ(3); + @$pb.TagNumber(4) + set height($core.int v) { $_setSignedInt32(3, v); } + @$pb.TagNumber(4) + $core.bool hasHeight() => $_has(3); + @$pb.TagNumber(4) + void clearHeight() => clearField(4); } class RawCell extends $pb.GeneratedMessage { @@ -620,6 +634,7 @@ class RawCell extends $pb.GeneratedMessage { ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') ..aOM(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: AnyData.create) + ..a<$core.int>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) ..hasRequiredFields = false ; @@ -629,6 +644,7 @@ class RawCell extends $pb.GeneratedMessage { $core.String? rowId, $core.String? fieldId, AnyData? data, + $core.int? height, }) { final _result = create(); if (id != null) { @@ -643,6 +659,9 @@ class RawCell extends $pb.GeneratedMessage { if (data != null) { _result.data = data; } + if (height != null) { + _result.height = height; + } return _result; } factory RawCell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -703,6 +722,15 @@ class RawCell extends $pb.GeneratedMessage { void clearData() => clearField(4); @$pb.TagNumber(4) AnyData ensureData() => $_ensure(3); + + @$pb.TagNumber(5) + $core.int get height => $_getIZ(4); + @$pb.TagNumber(5) + set height($core.int v) { $_setSignedInt32(4, v); } + @$pb.TagNumber(5) + $core.bool hasHeight() => $_has(4); + @$pb.TagNumber(5) + void clearHeight() => clearField(5); } class RepeatedRow extends $pb.GeneratedMessage { @@ -750,6 +778,7 @@ class Row extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Row', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..m<$core.String, Cell>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'Row.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: Cell.create) + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) ..hasRequiredFields = false ; @@ -757,6 +786,7 @@ class Row extends $pb.GeneratedMessage { factory Row({ $core.String? id, $core.Map<$core.String, Cell>? cellByFieldId, + $core.int? height, }) { final _result = create(); if (id != null) { @@ -765,6 +795,9 @@ class Row extends $pb.GeneratedMessage { if (cellByFieldId != null) { _result.cellByFieldId.addAll(cellByFieldId); } + if (height != null) { + _result.height = height; + } return _result; } factory Row.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -799,6 +832,15 @@ class Row extends $pb.GeneratedMessage { @$pb.TagNumber(2) $core.Map<$core.String, Cell> get cellByFieldId => $_getMap(1); + + @$pb.TagNumber(3) + $core.int get height => $_getIZ(2); + @$pb.TagNumber(3) + set height($core.int v) { $_setSignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasHeight() => $_has(2); + @$pb.TagNumber(3) + void clearHeight() => clearField(3); } class Cell 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 9a97445271..81257592ac 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 @@ -122,6 +122,7 @@ const RawRow$json = const { const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, const {'1': 'cell_by_field_id', '3': 3, '4': 3, '5': 11, '6': '.RawRow.CellByFieldIdEntry', '10': 'cellByFieldId'}, + const {'1': 'height', '3': 4, '4': 1, '5': 5, '10': 'height'}, ], '3': const [RawRow_CellByFieldIdEntry$json], }; @@ -137,7 +138,7 @@ const RawRow_CellByFieldIdEntry$json = const { }; /// Descriptor for `RawRow`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rawRowDescriptor = $convert.base64Decode('CgZSYXdSb3cSDgoCaWQYASABKAlSAmlkEhcKB2dyaWRfaWQYAiABKAlSBmdyaWRJZBJDChBjZWxsX2J5X2ZpZWxkX2lkGAMgAygLMhouUmF3Um93LkNlbGxCeUZpZWxkSWRFbnRyeVINY2VsbEJ5RmllbGRJZBpKChJDZWxsQnlGaWVsZElkRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSHgoFdmFsdWUYAiABKAsyCC5SYXdDZWxsUgV2YWx1ZToCOAE='); +final $typed_data.Uint8List rawRowDescriptor = $convert.base64Decode('CgZSYXdSb3cSDgoCaWQYASABKAlSAmlkEhcKB2dyaWRfaWQYAiABKAlSBmdyaWRJZBJDChBjZWxsX2J5X2ZpZWxkX2lkGAMgAygLMhouUmF3Um93LkNlbGxCeUZpZWxkSWRFbnRyeVINY2VsbEJ5RmllbGRJZBIWCgZoZWlnaHQYBCABKAVSBmhlaWdodBpKChJDZWxsQnlGaWVsZElkRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSHgoFdmFsdWUYAiABKAsyCC5SYXdDZWxsUgV2YWx1ZToCOAE='); @$core.Deprecated('Use rawCellDescriptor instead') const RawCell$json = const { '1': 'RawCell', @@ -146,11 +147,12 @@ const RawCell$json = const { const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, const {'1': 'data', '3': 4, '4': 1, '5': 11, '6': '.AnyData', '10': 'data'}, + const {'1': 'height', '3': 5, '4': 1, '5': 5, '10': 'height'}, ], }; /// Descriptor for `RawCell`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rawCellDescriptor = $convert.base64Decode('CgdSYXdDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhwKBGRhdGEYBCABKAsyCC5BbnlEYXRhUgRkYXRh'); +final $typed_data.Uint8List rawCellDescriptor = $convert.base64Decode('CgdSYXdDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhwKBGRhdGEYBCABKAsyCC5BbnlEYXRhUgRkYXRhEhYKBmhlaWdodBgFIAEoBVIGaGVpZ2h0'); @$core.Deprecated('Use repeatedRowDescriptor instead') const RepeatedRow$json = const { '1': 'RepeatedRow', @@ -167,6 +169,7 @@ const Row$json = const { '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'cell_by_field_id', '3': 2, '4': 3, '5': 11, '6': '.Row.CellByFieldIdEntry', '10': 'cellByFieldId'}, + const {'1': 'height', '3': 3, '4': 1, '5': 5, '10': 'height'}, ], '3': const [Row_CellByFieldIdEntry$json], }; @@ -182,7 +185,7 @@ const Row_CellByFieldIdEntry$json = const { }; /// Descriptor for `Row`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rowDescriptor = $convert.base64Decode('CgNSb3cSDgoCaWQYASABKAlSAmlkEkAKEGNlbGxfYnlfZmllbGRfaWQYAiADKAsyFy5Sb3cuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkGkcKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIbCgV2YWx1ZRgCIAEoCzIFLkNlbGxSBXZhbHVlOgI4AQ=='); +final $typed_data.Uint8List rowDescriptor = $convert.base64Decode('CgNSb3cSDgoCaWQYASABKAlSAmlkEkAKEGNlbGxfYnlfZmllbGRfaWQYAiADKAsyFy5Sb3cuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgDIAEoBVIGaGVpZ2h0GkcKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIbCgV2YWx1ZRgCIAEoCzIFLkNlbGxSBXZhbHVlOgI4AQ=='); @$core.Deprecated('Use cellDescriptor instead') const Cell$json = const { '1': 'Cell', diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 046fd85668..96755db623 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [lib] name = "dart_ffi" # this value will change depending on the target os -# default cdylib -crate-type = ["cdylib"] +# default staticlib +crate-type = ["staticlib"] [dependencies] diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs index e67d9176cd..1bce574abb 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs @@ -3,7 +3,6 @@ use flowy_collaboration::client_grid::make_grid_delta; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{Field, FieldOrder, FieldType, Grid, RawCell, RawRow, RowOrder}; use lib_infra::uuid; -use std::collections::HashMap; use std::sync::Arc; pub struct GridBuilder { @@ -24,40 +23,19 @@ impl GridBuilder { } pub fn add_field(mut self, name: &str, desc: &str, field_type: FieldType) -> Self { - let field = Field { - id: uuid(), - name: name.to_string(), - desc: desc.to_string(), - field_type, - frozen: false, - width: 100, - type_options: Default::default(), - }; + let field = Field::new(&uuid(), name, desc, field_type); self.fields.push(field); self } pub fn add_empty_row(mut self) -> Self { - let row = RawRow { - id: uuid(), - grid_id: self.grid_id.clone(), - cell_by_field_id: Default::default(), - }; + let row = RawRow::new(&uuid(), &self.grid_id, vec![]); self.rows.push(row); self } pub fn add_row(mut self, cells: Vec) -> Self { - let cell_by_field_id = cells - .into_iter() - .map(|cell| (cell.id.clone(), cell)) - .collect::>(); - - let row = RawRow { - id: uuid(), - grid_id: self.grid_id.clone(), - cell_by_field_id, - }; + let row = RawRow::new(&uuid(), &self.grid_id, cells); self.rows.push(row); self } 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 418807e058..9512e59b26 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -56,11 +56,7 @@ impl ClientGridEditor { } pub async fn create_empty_row(&self) -> FlowyResult<()> { - let row = RawRow { - id: uuid(), - grid_id: self.grid_id.clone(), - cell_by_field_id: Default::default(), - }; + let row = RawRow::new(&uuid(), &self.grid_id, vec![]); self.create_row(row).await?; Ok(()) } @@ -121,7 +117,11 @@ impl ClientGridEditor { let rows = raw_rows .into_par_iter() .map(|raw_row| { - let mut row = Row::new(&raw_row.id); + let mut row = Row { + id: raw_row.id.clone(), + cell_by_field_id: Default::default(), + height: raw_row.height, + }; row.cell_by_field_id = raw_row .cell_by_field_id .into_par_iter() diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index 926ca1e750..f8b616c22a 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -3,6 +3,9 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; use strum_macros::{Display, EnumIter, EnumString}; +pub const DEFAULT_ROW_HEIGHT: i32 = 36; +pub const DEFAULT_FIELD_WIDTH: i32 = 150; + pub trait GridIdentifiable { fn id(&self) -> &str; } @@ -90,6 +93,20 @@ pub struct Field { pub type_options: AnyData, } +impl Field { + pub fn new(id: &str, name: &str, desc: &str, field_type: FieldType) -> Self { + Self { + id: id.to_owned(), + name: name.to_string(), + desc: desc.to_string(), + field_type, + frozen: false, + width: DEFAULT_FIELD_WIDTH, + type_options: Default::default(), + } + } +} + impl GridIdentifiable for Field { fn id(&self) -> &str { &self.id @@ -245,6 +262,25 @@ pub struct RawRow { #[pb(index = 3)] pub cell_by_field_id: HashMap, + + #[pb(index = 4)] + pub height: i32, +} + +impl RawRow { + pub fn new(id: &str, grid_id: &str, cells: Vec) -> Self { + let cell_by_field_id = cells + .into_iter() + .map(|cell| (cell.id.clone(), cell)) + .collect::>(); + + Self { + id: id.to_owned(), + grid_id: grid_id.to_owned(), + cell_by_field_id, + height: DEFAULT_ROW_HEIGHT, + } + } } impl GridIdentifiable for RawRow { @@ -266,6 +302,9 @@ pub struct RawCell { #[pb(index = 4)] pub data: AnyData, + + #[pb(index = 5)] + pub height: i32, } #[derive(Debug, Default, ProtoBuf)] @@ -300,15 +339,9 @@ pub struct Row { #[pb(index = 2)] pub cell_by_field_id: HashMap, -} -impl Row { - pub fn new(row_id: &str) -> Self { - Self { - id: row_id.to_owned(), - cell_by_field_id: HashMap::new(), - } - } + #[pb(index = 3)] + pub height: i32, } #[derive(Debug, Default, ProtoBuf)] 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 f64dde24e6..b1a732e42e 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 @@ -1832,6 +1832,7 @@ pub struct RawRow { pub id: ::std::string::String, pub grid_id: ::std::string::String, pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, RawCell>, + pub height: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -1924,6 +1925,21 @@ impl RawRow { pub fn take_cell_by_field_id(&mut self) -> ::std::collections::HashMap<::std::string::String, RawCell> { ::std::mem::replace(&mut self.cell_by_field_id, ::std::collections::HashMap::new()) } + + // int32 height = 4; + + + pub fn get_height(&self) -> i32 { + self.height + } + pub fn clear_height(&mut self) { + self.height = 0; + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: i32) { + self.height = v; + } } impl ::protobuf::Message for RawRow { @@ -1944,6 +1960,13 @@ impl ::protobuf::Message for RawRow { 3 => { ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.height = tmp; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -1963,6 +1986,9 @@ impl ::protobuf::Message for RawRow { my_size += ::protobuf::rt::string_size(2, &self.grid_id); } my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id); + if self.height != 0 { + my_size += ::protobuf::rt::value_size(4, self.height, ::protobuf::wire_format::WireTypeVarint); + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -1976,6 +2002,9 @@ impl ::protobuf::Message for RawRow { os.write_string(2, &self.grid_id)?; } ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id, os)?; + if self.height != 0 { + os.write_int32(4, self.height)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -2029,6 +2058,11 @@ impl ::protobuf::Message for RawRow { |m: &RawRow| { &m.cell_by_field_id }, |m: &mut RawRow| { &mut m.cell_by_field_id }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "height", + |m: &RawRow| { &m.height }, + |m: &mut RawRow| { &mut m.height }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "RawRow", fields, @@ -2048,6 +2082,7 @@ impl ::protobuf::Clear for RawRow { self.id.clear(); self.grid_id.clear(); self.cell_by_field_id.clear(); + self.height = 0; self.unknown_fields.clear(); } } @@ -2071,6 +2106,7 @@ pub struct RawCell { pub row_id: ::std::string::String, pub field_id: ::std::string::String, pub data: ::protobuf::SingularPtrField, + pub height: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -2197,6 +2233,21 @@ impl RawCell { pub fn take_data(&mut self) -> AnyData { self.data.take().unwrap_or_else(|| AnyData::new()) } + + // int32 height = 5; + + + pub fn get_height(&self) -> i32 { + self.height + } + pub fn clear_height(&mut self) { + self.height = 0; + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: i32) { + self.height = v; + } } impl ::protobuf::Message for RawCell { @@ -2225,6 +2276,13 @@ impl ::protobuf::Message for RawCell { 4 => { ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.data)?; }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.height = tmp; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -2250,6 +2308,9 @@ impl ::protobuf::Message for RawCell { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } + if self.height != 0 { + my_size += ::protobuf::rt::value_size(5, self.height, ::protobuf::wire_format::WireTypeVarint); + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -2270,6 +2331,9 @@ impl ::protobuf::Message for RawCell { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; } + if self.height != 0 { + os.write_int32(5, self.height)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -2328,6 +2392,11 @@ impl ::protobuf::Message for RawCell { |m: &RawCell| { &m.data }, |m: &mut RawCell| { &mut m.data }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "height", + |m: &RawCell| { &m.height }, + |m: &mut RawCell| { &mut m.height }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "RawCell", fields, @@ -2348,6 +2417,7 @@ impl ::protobuf::Clear for RawCell { self.row_id.clear(); self.field_id.clear(); self.data.clear(); + self.height = 0; self.unknown_fields.clear(); } } @@ -2535,6 +2605,7 @@ pub struct Row { // message fields pub id: ::std::string::String, pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, Cell>, + pub height: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -2601,6 +2672,21 @@ impl Row { pub fn take_cell_by_field_id(&mut self) -> ::std::collections::HashMap<::std::string::String, Cell> { ::std::mem::replace(&mut self.cell_by_field_id, ::std::collections::HashMap::new()) } + + // int32 height = 3; + + + pub fn get_height(&self) -> i32 { + self.height + } + pub fn clear_height(&mut self) { + self.height = 0; + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: i32) { + self.height = v; + } } impl ::protobuf::Message for Row { @@ -2618,6 +2704,13 @@ impl ::protobuf::Message for Row { 2 => { ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.height = tmp; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -2634,6 +2727,9 @@ impl ::protobuf::Message for Row { my_size += ::protobuf::rt::string_size(1, &self.id); } my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(2, &self.cell_by_field_id); + if self.height != 0 { + my_size += ::protobuf::rt::value_size(3, self.height, ::protobuf::wire_format::WireTypeVarint); + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -2644,6 +2740,9 @@ impl ::protobuf::Message for Row { os.write_string(1, &self.id)?; } ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(2, &self.cell_by_field_id, os)?; + if self.height != 0 { + os.write_int32(3, self.height)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -2692,6 +2791,11 @@ impl ::protobuf::Message for Row { |m: &Row| { &m.cell_by_field_id }, |m: &mut Row| { &mut m.cell_by_field_id }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "height", + |m: &Row| { &m.height }, + |m: &mut Row| { &mut m.height }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "Row", fields, @@ -2710,6 +2814,7 @@ impl ::protobuf::Clear for Row { fn clear(&mut self) { self.id.clear(); self.cell_by_field_id.clear(); + self.height = 0; self.unknown_fields.clear(); } } @@ -4085,35 +4190,37 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\ \x20\x01(\tR\x05rowId\x12\x1e\n\nvisibility\x18\x03\x20\x01(\x08R\nvisib\ ility\"3\n\x10RepeatedRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\ - \t.RowOrderR\x05items\"\xc2\x01\n\x06RawRow\x12\x0e\n\x02id\x18\x01\x20\ + \t.RowOrderR\x05items\"\xda\x01\n\x06RawRow\x12\x0e\n\x02id\x18\x01\x20\ \x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\x12C\n\ \x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1a.RawRow.CellByFieldIdEntry\ - R\rcellByFieldId\x1aJ\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\ - \x20\x01(\tR\x03key\x12\x1e\n\x05value\x18\x02\x20\x01(\x0b2\x08.RawCell\ - R\x05value:\x028\x01\"i\n\x07RawCell\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ - \x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08fie\ - ld_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\ - \x0b2\x08.AnyDataR\x04data\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\ - \x01\x20\x03(\x0b2\x04.RowR\x05items\"\xa0\x01\n\x03Row\x12\x0e\n\x02id\ - \x18\x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\ - \x0b2\x17.Row.CellByFieldIdEntryR\rcellByFieldId\x1aG\n\x12CellByFieldId\ - Entry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\ - \x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\"K\n\x04Cell\x12\x0e\n\ - \x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08field_id\x18\x02\x20\x01(\ - \tR\x07fieldId\x12\x18\n\x07content\x18\x03\x20\x01(\tR\x07content\"e\n\ - \rCellChangeset\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06r\ - ow_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01\ - (\tR\x07fieldId\x12\x12\n\x04data\x18\x04\x20\x01(\tR\x04data\"'\n\x11Cr\ - eateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\ - \x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"d\n\x11Query\ - FieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\ - \x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldO\ - rders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ - \x06gridId\x120\n\nrow_orders\x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrder\ - R\trowOrders*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Numbe\ - r\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\ - \x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06\ - proto3\ + R\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06height\x1a\ + J\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\ + \x12\x1e\n\x05value\x18\x02\x20\x01(\x0b2\x08.RawCellR\x05value:\x028\ + \x01\"\x81\x01\n\x07RawCell\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ + \x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\ + \x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\ + \x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06heigh\ + t\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\ + \x05items\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ + \x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdE\ + ntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\ + \x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03ke\ + y\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\ + \"K\n\x04Cell\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08fie\ + ld_id\x18\x02\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x03\x20\ + \x01(\tR\x07content\"e\n\rCellChangeset\x12\x0e\n\x02id\x18\x01\x20\x01(\ + \tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08\ + field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x12\n\x04data\x18\x04\x20\ + \x01(\tR\x04data\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\ + \x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\t\ + R\x05value\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\ + \x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.Repe\ + atedFieldOrderR\x0bfieldOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07gri\ + d_id\x18\x01\x20\x01(\tR\x06gridId\x120\n\nrow_orders\x18\x02\x20\x01(\ + \x0b2\x11.RepeatedRowOrderR\trowOrders*d\n\tFieldType\x12\x0c\n\x08RichT\ + ext\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\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 79d6af77e1..04e82bea78 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 @@ -40,12 +40,14 @@ message RawRow { string id = 1; string grid_id = 2; map cell_by_field_id = 3; + int32 height = 4; } message RawCell { string id = 1; string row_id = 2; string field_id = 3; AnyData data = 4; + int32 height = 5; } message RepeatedRow { repeated Row items = 1; @@ -53,6 +55,7 @@ message RepeatedRow { message Row { string id = 1; map cell_by_field_id = 2; + int32 height = 3; } message Cell { string id = 1; From 808d848f621f6efbbf8f613d7b3bd38da467f656 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 8 Mar 2022 22:58:43 +0800 Subject: [PATCH 03/28] feat: cell border --- .../src/widgets/content/cell_container.dart | 8 ++++ .../grid/src/widgets/content/grid_cell.dart | 17 +-------- .../grid/src/widgets/content/grid_row.dart | 3 +- .../grid/src/widgets/header/header.dart | 4 +- .../grid/src/widgets/header/header_cell.dart | 38 +++++++++++-------- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart index 03f0e82115..5b771b8c92 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart @@ -1,5 +1,7 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra/theme.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; class CellContainer extends StatelessWidget { final Widget child; @@ -12,6 +14,9 @@ class CellContainer extends StatelessWidget { @override Widget build(BuildContext context) { + final theme = context.watch(); + final borderSide = BorderSide(color: theme.shader4, width: 0.4); + return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () {}, @@ -19,6 +24,9 @@ class CellContainer extends StatelessWidget { constraints: BoxConstraints( maxWidth: width, ), + decoration: BoxDecoration( + border: Border(right: borderSide, bottom: borderSide), + ), padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), child: Center(child: IntrinsicHeight(child: child)), ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart index 5c0dbabfea..5646376bf7 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart @@ -102,27 +102,14 @@ class RowLeading extends StatelessWidget { return Row( children: const [ CreateRowButton(), + DrawRowButton(), ], ); } - return const Spacer(); + return const SizedBox.expand(); }, ); - - // return GestureDetector( - // behavior: HitTestBehavior.translucent, - // onTap: () {}, - // child: MouseHoverBuilder( - // builder: (_, isHovered) => Container( - // width: GridSize.startHeaderPadding, - // decoration: CellDecoration.box( - // color: isHovered ? Colors.red.withOpacity(.1) : Colors.white, - // ), - // padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), - // ), - // ), - // ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index c251546cce..3ef343493a 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -1,5 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -41,7 +42,7 @@ class GridRowWidget extends StatelessWidget { List _buildCells() { return [ - RowLeading(rowId: data.row.id), + SizedBox(width: GridSize.startHeaderPadding, child: RowLeading(rowId: data.row.id)), ...data.fields.map( (field) { final cellData = data.cellMap[field.id]; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index 9f894f8ee5..c70d3ce3b2 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -40,9 +40,7 @@ class GridHeader extends StatelessWidget { fields.asMap().forEach((index, field) { final header = HeaderCellContainer( width: field.width.toDouble(), - child: HeaderCell( - field, - ), + child: HeaderCell(field), ); // diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index ca59069f3f..e059208aff 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -1,6 +1,10 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'constants.dart'; class HeaderCell extends StatelessWidget { @@ -9,10 +13,16 @@ class HeaderCell extends StatelessWidget { @override Widget build(BuildContext context) { - return Text( - field.name, - style: const TextStyle(fontSize: 15.0, color: Colors.black), + final theme = context.watch(); + return FlowyButton( + text: FlowyText.medium(field.name), + hoverColor: theme.hover, + onTap: () {}, ); + // return Text( + // field.name, + // style: const TextStyle(fontSize: 15.0, color: Colors.black), + // ); } } @@ -23,18 +33,15 @@ class HeaderCellContainer extends StatelessWidget { @override Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () {}, - child: Container( - width: width, - decoration: BoxDecoration( - border: Border.all(color: Colors.black26, width: 0.5), - color: GridHeaderConstants.backgroundColor, - ), - padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), - child: child, + final theme = context.watch(); + final borderSide = BorderSide(color: theme.shader4, width: 0.4); + return Container( + width: width, + decoration: BoxDecoration( + border: Border(top: borderSide, right: borderSide, bottom: borderSide), ), + padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), + child: child, ); } } @@ -44,9 +51,8 @@ class HeaderCellLeading extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( + return SizedBox( width: GridSize.startHeaderPadding, - color: GridHeaderConstants.backgroundColor, ); } } From 00db755c29355aca7e3d40cf80ebd26c4e40394d Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 9 Mar 2022 09:31:06 +0800 Subject: [PATCH 04/28] feat: add cloumn bloc --- .../lib/startup/home_deps_resolver.dart | 8 ++ .../application/grid/column_bloc.dart | 43 +++++++++ .../application/grid/column_service.dart | 1 + .../lib/workspace/application/grid/data.dart | 6 ++ .../workspace/application/grid/prelude.dart | 2 + .../plugins/grid/src/grid_page.dart | 10 +-- .../plugins/grid/src/layout/layout.dart | 2 +- .../plugins/grid/src/layout/sizes.dart | 30 +++++-- .../src/widgets/content/cell_container.dart | 2 +- .../grid/src/widgets/content/grid_cell.dart | 61 ------------- .../grid/src/widgets/content/grid_row.dart | 74 ++++++++++++++- .../grid/src/widgets/footer/grid_footer.dart | 46 +++++----- .../grid/src/widgets/header/header.dart | 90 +++++++++++++++---- .../grid/src/widgets/header/header_cell.dart | 16 +--- .../lib/style_widget/button.dart | 2 +- 15 files changed, 255 insertions(+), 138 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/column_service.dart diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 9a2a47301e..54275b95b3 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -12,6 +12,7 @@ import 'package:app_flowy/workspace/application/menu/prelude.dart'; import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:get_it/get_it.dart'; @@ -102,6 +103,13 @@ class HomeDepsResolver { ), ); + getIt.registerFactoryParam, void>( + (data, _) => ColumnBloc( + data: GridColumnData(fields: data), + service: ColumnService(), + ), + ); + // trash getIt.registerLazySingleton(() => TrashService()); getIt.registerLazySingleton(() => TrashListener()); diff --git a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart new file mode 100644 index 0000000000..844360fa9b --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart @@ -0,0 +1,43 @@ +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 'package:dartz/dartz.dart'; +import 'dart:async'; +import 'column_service.dart'; +import 'data.dart'; + +part 'column_bloc.freezed.dart'; + +class ColumnBloc extends Bloc { + final ColumnService service; + final GridColumnData data; + + ColumnBloc({required this.data, required this.service}) : super(ColumnState.initial(data.fields)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialColumn value) async {}, + createColumn: (_CreateColumn value) {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +abstract class ColumnEvent with _$ColumnEvent { + const factory ColumnEvent.initial() = _InitialColumn; + const factory ColumnEvent.createColumn() = _CreateColumn; +} + +@freezed +abstract class ColumnState with _$ColumnState { + const factory ColumnState({required List fields}) = _ColumnState; + + factory ColumnState.initial(List fields) => ColumnState(fields: fields); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/column_service.dart b/frontend/app_flowy/lib/workspace/application/grid/column_service.dart new file mode 100644 index 0000000000..c074dcf616 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/column_service.dart @@ -0,0 +1 @@ +class ColumnService {} diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart index 6c815b7f35..b0e260fe8e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -33,3 +33,9 @@ class GridRowData { required this.cellMap, }); } + +class GridColumnData { + final List fields; + + GridColumnData({required this.fields}); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index bf48b7cc8b..3cbe922a58 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -3,3 +3,5 @@ export 'row_bloc.dart'; export 'row_service.dart'; export 'grid_service.dart'; export 'data.dart'; +export 'column_service.dart'; +export 'column_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index ae3934b7cb..ba89c63662 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -111,7 +111,7 @@ class _GridBodyState extends State { slivers: [ _buildHeader(gridInfo.fields), _buildRows(gridInfo), - _builderFooter(context), + const GridFooter(), ], ), ), @@ -145,12 +145,4 @@ class _GridBodyState extends State { ), ); } - - Widget _builderFooter(BuildContext context) { - return GridFooter( - onAddRow: () { - context.read().add(const GridEvent.createRow()); - }, - ); - } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart index 5b58d3c1c5..3f076fc89f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart @@ -8,6 +8,6 @@ class GridLayout { final fieldsWidth = fields.map((field) => field.width.toDouble()).reduce((value, element) => value + element); - return fieldsWidth + GridSize.startHeaderPadding; + return fieldsWidth + GridSize.leadingHeaderPadding + GridSize.trailHeaderPadding; } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart index e577311200..e669a78217 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart @@ -1,15 +1,29 @@ -class GridInsets { - static double scale = 1; - - static double get horizontal => 8 * scale; - static double get vertical => 8 * scale; -} +import 'package:flutter/widgets.dart'; class GridSize { static double scale = 1; static double get scrollBarSize => 12 * scale; - static double get headerHeight => 50 * scale; + static double get headerHeight => 40 * scale; static double get footerHeight => 40 * scale; - static double get startHeaderPadding => 30 * scale; + static double get leadingHeaderPadding => 30 * scale; + static double get trailHeaderPadding => 140 * scale; + static double get headerContentPadding => 8 * scale; + static double get cellContentPadding => 8 * scale; + // + static EdgeInsets get headerContentInsets => EdgeInsets.symmetric( + horizontal: GridSize.headerContentPadding, + vertical: GridSize.headerContentPadding, + ); + static EdgeInsets get cellContentInsets => EdgeInsets.symmetric( + horizontal: GridSize.cellContentPadding, + vertical: GridSize.cellContentPadding, + ); + + static EdgeInsets get footerContentInsets => EdgeInsets.fromLTRB( + 0, + GridSize.headerContentPadding, + GridSize.headerContentPadding, + GridSize.headerContentPadding, + ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart index 5b771b8c92..0fbdc3b53c 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart @@ -27,7 +27,7 @@ class CellContainer extends StatelessWidget { decoration: BoxDecoration( border: Border(right: borderSide, bottom: borderSide), ), - padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), + padding: GridSize.cellContentInsets, child: Center(child: IntrinsicHeight(child: child)), ), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart index 5646376bf7..be04555bd4 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart @@ -1,15 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/row_bloc.dart'; -import 'package:app_flowy/workspace/presentation/home/menu/app/header/add_button.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:flowy_infra/image.dart'; -import 'package:flowy_infra/theme.dart'; -import 'package:flowy_infra_ui/style_widget/icon_button.dart'; -import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; - -import 'cell_decoration.dart'; -// ignore: import_of_legacy_library_into_null_safe /// The interface of base cell. abstract class GridCellWidget extends StatelessWidget { @@ -89,53 +78,3 @@ class BlankCell extends GridCellWidget { return Container(); } } - -class RowLeading extends StatelessWidget { - final String rowId; - const RowLeading({required this.rowId, Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - if (state.isHighlight) { - return Row( - children: const [ - CreateRowButton(), - DrawRowButton(), - ], - ); - } - - return const SizedBox.expand(); - }, - ); - } -} - -class CreateRowButton extends StatelessWidget { - const CreateRowButton({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - return Tooltip( - message: '', - child: FlowyIconButton( - hoverColor: theme.hover, - width: 22, - onPressed: () => context.read().add(const RowEvent.createRow()), - icon: svg("home/add"), - ), - ); - } -} - -class DrawRowButton extends StatelessWidget { - const DrawRowButton({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container(); - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index 3ef343493a..3e43d4fd8d 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -1,7 +1,9 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'cell_builder.dart'; @@ -42,7 +44,10 @@ class GridRowWidget extends StatelessWidget { List _buildCells() { return [ - SizedBox(width: GridSize.startHeaderPadding, child: RowLeading(rowId: data.row.id)), + SizedBox( + width: GridSize.leadingHeaderPadding, + child: LeadingRow(rowId: data.row.id), + ), ...data.fields.map( (field) { final cellData = data.cellMap[field.id]; @@ -51,7 +56,72 @@ class GridRowWidget extends StatelessWidget { child: GridCellBuilder.buildCell(field, cellData), ); }, + ), + SizedBox( + width: GridSize.trailHeaderPadding, + child: TrailingRow(rowId: data.row.id), ) ].toList(); } } + +class LeadingRow extends StatelessWidget { + final String rowId; + const LeadingRow({required this.rowId, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state.isHighlight) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + CreateRowButton(), + ], + ); + } + return const SizedBox.expand(); + }, + ); + } +} + +class TrailingRow extends StatelessWidget { + final String rowId; + const TrailingRow({required this.rowId, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final borderSide = BorderSide(color: theme.shader4, width: 0.4); + + return BlocBuilder( + builder: (context, state) { + return Container( + width: GridSize.trailHeaderPadding, + decoration: BoxDecoration( + border: Border(bottom: borderSide), + ), + padding: GridSize.cellContentInsets, + ); + }, + ); + } +} + +class CreateRowButton extends StatelessWidget { + const CreateRowButton({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return FlowyIconButton( + hoverColor: theme.hover, + width: 22, + onPressed: () => context.read().add(const RowEvent.createRow()), + iconPadding: const EdgeInsets.all(3), + icon: svg("home/add"), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart index 6e1befe18e..5ca3bf0f6b 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart @@ -1,22 +1,28 @@ +import 'package:app_flowy/workspace/application/grid/row_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; - -import '../content/cell_decoration.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; class GridFooter extends StatelessWidget { - final VoidCallback? onAddRow; - const GridFooter({Key? key, required this.onAddRow}) : super(key: key); + const GridFooter({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return SliverToBoxAdapter( child: SizedBox( height: GridSize.footerHeight, - child: Row( - children: [ - AddRowButton(onTap: onAddRow), - ], + child: Padding( + padding: GridSize.headerContentInsets, + child: Row( + children: [ + SizedBox(width: GridSize.leadingHeaderPadding), + const SizedBox(width: 120, child: AddRowButton()), + ], + ), ), ), ); @@ -24,24 +30,16 @@ class GridFooter extends StatelessWidget { } class AddRowButton extends StatelessWidget { - final VoidCallback? onTap; - const AddRowButton({Key? key, required this.onTap}) : super(key: key); + const AddRowButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: onTap, - child: MouseHoverBuilder( - builder: (_, isHovered) => Container( - width: GridSize.startHeaderPadding, - height: GridSize.footerHeight, - decoration: CellDecoration.box( - color: isHovered ? Colors.red.withOpacity(.1) : Colors.white, - ), - child: const Icon(Icons.add, size: 16), - ), - ), + final theme = context.watch(); + return FlowyButton( + text: const FlowyText.medium('New row', fontSize: 12), + hoverColor: theme.hover, + onTap: () => context.read().add(const RowEvent.createRow()), + icon: svg("home/add"), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index c70d3ce3b2..d3cf4a5255 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -1,6 +1,13 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/column_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'header_cell.dart'; @@ -31,28 +38,77 @@ class GridHeaderDelegate extends SliverPersistentHeaderDelegate { class GridHeader extends StatelessWidget { final List fields; - const GridHeader({required this.fields, Key? key}) : super(key: key); @override Widget build(BuildContext context) { - final headers = List.empty(growable: true); - fields.asMap().forEach((index, field) { - final header = HeaderCellContainer( - width: field.width.toDouble(), - child: HeaderCell(field), - ); + return BlocProvider( + create: (context) => getIt(param1: fields), + child: BlocBuilder( + builder: (context, state) { + final headers = state.fields + .map( + (field) => HeaderCellContainer( + width: field.width.toDouble(), + child: HeaderCell(field), + ), + ) + .toList(); - // - headers.add(header); - }); - - return Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const HeaderCellLeading(), - ...headers, - ], + return Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const LeadingHeaderCell(), + ...headers, + const TrailingHeaderCell(), + ], + ); + }, + ), + ); + } +} + +class LeadingHeaderCell extends StatelessWidget { + const LeadingHeaderCell({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + width: GridSize.leadingHeaderPadding, + ); + } +} + +class TrailingHeaderCell extends StatelessWidget { + const TrailingHeaderCell({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final borderSide = BorderSide(color: theme.shader4, width: 0.4); + return Container( + width: GridSize.trailHeaderPadding, + decoration: BoxDecoration( + border: Border(top: borderSide, bottom: borderSide), + ), + padding: GridSize.headerContentInsets, + child: const CreateColumnButton(), + ); + } +} + +class CreateColumnButton extends StatelessWidget { + const CreateColumnButton({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + return FlowyButton( + text: const FlowyText.medium('New column', fontSize: 12), + hoverColor: theme.hover, + onTap: () => context.read().add(const ColumnEvent.createColumn()), + icon: svg("home/add"), ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index e059208aff..9b77af4b3e 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -5,7 +5,6 @@ import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'constants.dart'; class HeaderCell extends StatelessWidget { final Field field; @@ -15,7 +14,7 @@ class HeaderCell extends StatelessWidget { Widget build(BuildContext context) { final theme = context.watch(); return FlowyButton( - text: FlowyText.medium(field.name), + text: FlowyText.medium(field.name, fontSize: 12), hoverColor: theme.hover, onTap: () {}, ); @@ -40,19 +39,8 @@ class HeaderCellContainer extends StatelessWidget { decoration: BoxDecoration( border: Border(top: borderSide, right: borderSide, bottom: borderSide), ), - padding: EdgeInsets.symmetric(vertical: GridInsets.vertical, horizontal: GridInsets.horizontal), + padding: GridSize.headerContentInsets, child: child, ); } } - -class HeaderCellLeading extends StatelessWidget { - const HeaderCellLeading({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - width: GridSize.startHeaderPadding, - ); - } -} diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart index 6b67081ca2..b7d8ea4e88 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart @@ -24,7 +24,7 @@ class FlowyButton extends StatelessWidget { return InkWell( onTap: onTap, child: FlowyHover( - config: HoverDisplayConfig(borderRadius: Corners.s6Border, hoverColor: hoverColor), + config: HoverDisplayConfig(borderRadius: Corners.s5Border, hoverColor: hoverColor), builder: (context, onHover) => _render(), ), ); From 321682717cbe4f01ca362331792d4f0dd12a62c1 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 9 Mar 2022 12:11:27 +0800 Subject: [PATCH 05/28] chore: opti row rebuild --- .../lib/workspace/application/grid/data.dart | 14 +- .../workspace/application/grid/row_bloc.dart | 23 +-- .../plugins/grid/src/grid_page.dart | 2 +- .../src/widgets/content/cell_container.dart | 13 +- .../grid/src/widgets/content/grid_row.dart | 133 ++++++++++-------- .../grid/src/widgets/header/header_cell.dart | 4 - 6 files changed, 105 insertions(+), 84 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart index b0e260fe8e..c32f87f1a2 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:equatable/equatable.dart'; class GridInfo { List rows; @@ -23,15 +24,18 @@ class GridInfo { } } -class GridRowData { - Row row; - List fields; - Map cellMap; - GridRowData({ +class GridRowData extends Equatable { + final Row row; + final List fields; + final Map cellMap; + const GridRowData({ required this.row, required this.fields, required this.cellMap, }); + + @override + List get props => [row.hashCode, cellMap]; } class GridColumnData { diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart index 8feb26e4c7..9af22beba9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart @@ -1,6 +1,5 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:dartz/dartz.dart'; import 'dart:async'; import 'data.dart'; import 'row_service.dart'; @@ -9,18 +8,18 @@ part 'row_bloc.freezed.dart'; class RowBloc extends Bloc { final RowService service; - final GridRowData data; - RowBloc({required this.data, required this.service}) : super(RowState.initial()) { + RowBloc({required GridRowData data, required this.service}) : super(RowState.initial(data)) { on( (event, emit) async { await event.map( initial: (_InitialRow value) async {}, createRow: (_CreateRow value) {}, - highlightRow: (_HighlightRow value) { - emit(state.copyWith( - isHighlight: value.rowId.fold(() => false, (rowId) => rowId == data.row.id), - )); + activeRow: (_ActiveRow value) { + emit(state.copyWith(active: true)); + }, + disactiveRow: (_DisactiveRow value) { + emit(state.copyWith(active: false)); }, ); }, @@ -35,16 +34,18 @@ class RowBloc extends Bloc { @freezed abstract class RowEvent with _$RowEvent { - const factory RowEvent.initial() = _InitialRow; + const factory RowEvent.initial(GridRowData data) = _InitialRow; const factory RowEvent.createRow() = _CreateRow; - const factory RowEvent.highlightRow(Option rowId) = _HighlightRow; + const factory RowEvent.activeRow() = _ActiveRow; + const factory RowEvent.disactiveRow() = _DisactiveRow; } @freezed abstract class RowState with _$RowState { const factory RowState({ - required bool isHighlight, + required GridRowData data, + required bool active, }) = _RowState; - factory RowState.initial() => const RowState(isHighlight: false); + factory RowState.initial(GridRowData data) => RowState(data: data, active: false); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index ba89c63662..7435ea0e5f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -139,7 +139,7 @@ class _GridBodyState extends State { delegate: SliverChildBuilderDelegate( (context, index) { final data = gridInfo.rowAtIndex(index); - return RepaintBoundary(child: GridRowWidget(data)); + return RepaintBoundary(child: GridRowWidget(data: data)); }, childCount: gridInfo.numberOfRows(), ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart index 0fbdc3b53c..56cc4e174f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart @@ -1,9 +1,10 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra/theme.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -class CellContainer extends StatelessWidget { +class CellContainer extends StatefulWidget { final Widget child; final double width; const CellContainer({ @@ -12,23 +13,27 @@ class CellContainer extends StatelessWidget { required this.width, }) : super(key: key); + @override + State createState() => _CellContainerState(); +} + +class _CellContainerState extends State { @override Widget build(BuildContext context) { final theme = context.watch(); final borderSide = BorderSide(color: theme.shader4, width: 0.4); - return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () {}, child: Container( constraints: BoxConstraints( - maxWidth: width, + maxWidth: widget.width, ), decoration: BoxDecoration( border: Border(right: borderSide, bottom: borderSide), ), padding: GridSize.cellContentInsets, - child: Center(child: IntrinsicHeight(child: child)), + child: Center(child: IntrinsicHeight(child: widget.child)), ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index 3e43d4fd8d..dce4b61d4f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -8,88 +8,103 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'cell_builder.dart'; import 'cell_container.dart'; -import 'grid_cell.dart'; -import 'package:dartz/dartz.dart'; -class GridRowWidget extends StatelessWidget { +class GridRowWidget extends StatefulWidget { final GridRowData data; - final Function(bool)? onHoverChange; - const GridRowWidget(this.data, {Key? key, this.onHoverChange}) : super(key: key); + GridRowWidget({required this.data, Key? key}) : super(key: ObjectKey(data.row.id)); + + @override + State createState() => _GridRowWidgetState(); +} + +class _GridRowWidgetState extends State { + late RowBloc _rowBloc; + + @override + void initState() { + _rowBloc = getIt(param1: widget.data); + super.initState(); + } @override Widget build(BuildContext context) { - return BlocProvider( - create: (context) => getIt(param1: data), - child: BlocBuilder( - builder: (context, state) { - return GestureDetector( - behavior: HitTestBehavior.translucent, - child: MouseRegion( - cursor: SystemMouseCursors.click, - onEnter: (p) => context.read().add(RowEvent.highlightRow(some(data.row.id))), - onExit: (p) => context.read().add(RowEvent.highlightRow(none())), - child: SizedBox( - height: data.row.height.toDouble(), - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: _buildCells(), - ), - ), + return BlocProvider.value( + value: _rowBloc, + child: GestureDetector( + behavior: HitTestBehavior.translucent, + child: MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), + onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), + child: SizedBox( + height: _rowBloc.state.data.row.height.toDouble(), + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const LeadingRow(), + _buildCells(), + const TrailingRow(), + ], ), - ); - }, + ), + ), ), ); } - List _buildCells() { - return [ - SizedBox( - width: GridSize.leadingHeaderPadding, - child: LeadingRow(rowId: data.row.id), - ), - ...data.fields.map( - (field) { - final cellData = data.cellMap[field.id]; - return CellContainer( - width: field.width.toDouble(), - child: GridCellBuilder.buildCell(field, cellData), - ); - }, - ), - SizedBox( - width: GridSize.trailHeaderPadding, - child: TrailingRow(rowId: data.row.id), - ) - ].toList(); + @override + Future dispose() async { + _rowBloc.close(); + super.dispose(); + } + + Widget _buildCells() { + return BlocBuilder( + buildWhen: (p, c) => p.data != c.data, + builder: (context, state) { + return Row( + key: ValueKey(state.data.row.id), + children: state.data.fields.map( + (field) { + final cellData = state.data.cellMap[field.id]; + return CellContainer( + width: field.width.toDouble(), + child: GridCellBuilder.buildCell(field, cellData), + ); + }, + ).toList(), + ); + }, + ); } } class LeadingRow extends StatelessWidget { - final String rowId; - const LeadingRow({required this.rowId, Key? key}) : super(key: key); + const LeadingRow({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - if (state.isHighlight) { - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: const [ - CreateRowButton(), - ], - ); - } - return const SizedBox.expand(); + return BlocSelector( + selector: (state) => state.active, + builder: (context, isActive) { + return SizedBox( + width: GridSize.leadingHeaderPadding, + child: isActive + ? Row( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + CreateRowButton(), + ], + ) + : null, + ); }, ); } } class TrailingRow extends StatelessWidget { - final String rowId; - const TrailingRow({required this.rowId, Key? key}) : super(key: key); + const TrailingRow({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index 9b77af4b3e..aacdcd251e 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -18,10 +18,6 @@ class HeaderCell extends StatelessWidget { hoverColor: theme.hover, onTap: () {}, ); - // return Text( - // field.name, - // style: const TextStyle(fontSize: 15.0, color: Colors.black), - // ); } } From fe8811392b79332274cae91fa6535bb58baf75f9 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 9 Mar 2022 16:11:24 +0800 Subject: [PATCH 06/28] feat: config cells --- .../lib/startup/home_deps_resolver.dart | 40 ++++++++++ .../grid/cell_bloc/cell_service.dart | 1 + .../grid/cell_bloc/checkbox_cell_bloc.dart | 46 +++++++++++ .../grid/cell_bloc/date_cell_bloc.dart | 46 +++++++++++ .../grid/cell_bloc/number_cell_bloc.dart | 46 +++++++++++ .../grid/cell_bloc/selection_cell_bloc.dart | 46 +++++++++++ .../grid/cell_bloc/text_cell_bloc.dart | 48 +++++++++++ .../application/grid/column_bloc.dart | 1 - .../workspace/application/grid/prelude.dart | 6 ++ .../workspace/application/grid/row_bloc.dart | 2 +- .../presentation/plugins/doc/document.dart | 1 + .../plugins/grid/src/layout/sizes.dart | 1 + .../src/widgets/content/cell_builder.dart | 44 +++++++--- .../src/widgets/content/checkbox_cell.dart | 47 +++++++++++ .../grid/src/widgets/content/date_cell.dart | 47 +++++++++++ .../grid/src/widgets/content/grid_cell.dart | 80 ------------------- .../grid/src/widgets/content/grid_row.dart | 6 +- .../grid/src/widgets/content/number_cell.dart | 47 +++++++++++ .../src/widgets/content/selection_cell.dart | 75 +++++++++++++++++ .../grid/src/widgets/content/text_cell.dart | 70 ++++++++++++++++ .../grid/src/widgets/header/header.dart | 2 +- .../rust-lib/flowy-grid/src/event_handler.rs | 15 +++- frontend/rust-lib/flowy-grid/src/event_map.rs | 6 +- .../flowy-grid/src/services/grid_editor.rs | 14 ++++ 24 files changed, 636 insertions(+), 101 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart delete mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 54275b95b3..5b91d8a545 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -110,6 +110,46 @@ class HomeDepsResolver { ), ); + getIt.registerFactoryParam( + (field, cell) => TextCellBloc( + field: field, + cell: cell, + service: CellService(), + ), + ); + + getIt.registerFactoryParam( + (field, cell) => SelectionCellBloc( + field: field, + cell: cell, + service: CellService(), + ), + ); + + getIt.registerFactoryParam( + (field, cell) => NumberCellBloc( + field: field, + cell: cell, + service: CellService(), + ), + ); + + getIt.registerFactoryParam( + (field, cell) => DateCellBloc( + field: field, + cell: cell, + service: CellService(), + ), + ); + + getIt.registerFactoryParam( + (field, cell) => CheckboxCellBloc( + field: field, + cell: cell, + service: CellService(), + ), + ); + // trash getIt.registerLazySingleton(() => TrashService()); getIt.registerLazySingleton(() => TrashListener()); diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart new file mode 100644 index 0000000000..c5098155cb --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -0,0 +1 @@ +class CellService {} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart new file mode 100644 index 0000000000..8f0de7fb32 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -0,0 +1,46 @@ +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'; +import 'cell_service.dart'; + +part 'checkbox_cell_bloc.freezed.dart'; + +class CheckboxCellBloc extends Bloc { + final Field field; + final Cell? cell; + final CellService service; + + CheckboxCellBloc({ + required this.field, + required this.cell, + required this.service, + }) : super(CheckboxCellState.initial(cell)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialCell value) async {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +abstract class CheckboxCellEvent with _$CheckboxCellEvent { + const factory CheckboxCellEvent.initial() = _InitialCell; +} + +@freezed +abstract class CheckboxCellState with _$CheckboxCellState { + const factory CheckboxCellState({ + required Cell? cell, + }) = _CheckboxCellState; + + factory CheckboxCellState.initial(Cell? cell) => CheckboxCellState(cell: cell); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart new file mode 100644 index 0000000000..c8b5e97f2d --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -0,0 +1,46 @@ +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'; +import 'cell_service.dart'; + +part 'date_cell_bloc.freezed.dart'; + +class DateCellBloc extends Bloc { + final Field field; + final Cell? cell; + final CellService service; + + DateCellBloc({ + required this.field, + required this.cell, + required this.service, + }) : super(DateCellState.initial(cell)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialCell value) async {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +abstract class DateCellEvent with _$DateCellEvent { + const factory DateCellEvent.initial() = _InitialCell; +} + +@freezed +abstract class DateCellState with _$DateCellState { + const factory DateCellState({ + required Cell? cell, + }) = _DateCellState; + + factory DateCellState.initial(Cell? cell) => DateCellState(cell: cell); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart new file mode 100644 index 0000000000..b216550a81 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -0,0 +1,46 @@ +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'; +import 'cell_service.dart'; + +part 'number_cell_bloc.freezed.dart'; + +class NumberCellBloc extends Bloc { + final Field field; + final Cell? cell; + final CellService service; + + NumberCellBloc({ + required this.field, + required this.cell, + required this.service, + }) : super(NumberCellState.initial(cell)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialCell value) async {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +abstract class NumberCellEvent with _$NumberCellEvent { + const factory NumberCellEvent.initial() = _InitialCell; +} + +@freezed +abstract class NumberCellState with _$NumberCellState { + const factory NumberCellState({ + required Cell? cell, + }) = _NumberCellState; + + factory NumberCellState.initial(Cell? cell) => NumberCellState(cell: cell); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart new file mode 100644 index 0000000000..5e7a6e8e22 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -0,0 +1,46 @@ +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'; +import 'cell_service.dart'; + +part 'selection_cell_bloc.freezed.dart'; + +class SelectionCellBloc extends Bloc { + final Field field; + final Cell? cell; + final CellService service; + + SelectionCellBloc({ + required this.field, + required this.cell, + required this.service, + }) : super(SelectionCellState.initial(cell)) { + on( + (event, emit) async { + await event.map( + initial: (_InitialCell value) async {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +abstract class SelectionCellEvent with _$SelectionCellEvent { + const factory SelectionCellEvent.initial() = _InitialCell; +} + +@freezed +abstract class SelectionCellState with _$SelectionCellState { + const factory SelectionCellState({ + required Cell? cell, + }) = _SelectionCellState; + + factory SelectionCellState.initial(Cell? cell) => SelectionCellState(cell: cell); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart new file mode 100644 index 0000000000..cce4ff9224 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart @@ -0,0 +1,48 @@ +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'; +import 'cell_service.dart'; + +part 'text_cell_bloc.freezed.dart'; + +class TextCellBloc extends Bloc { + final Field field; + final Cell? cell; + final CellService service; + + TextCellBloc({ + required this.field, + required this.cell, + required this.service, + }) : super(TextCellState.initial(cell?.content ?? "")) { + on( + (event, emit) async { + await event.map( + initial: (_InitialCell value) async {}, + updateText: (_UpdateText value) {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } +} + +@freezed +abstract class TextCellEvent with _$TextCellEvent { + const factory TextCellEvent.initial() = _InitialCell; + const factory TextCellEvent.updateText(String text) = _UpdateText; +} + +@freezed +abstract class TextCellState with _$TextCellState { + const factory TextCellState({ + required String content, + }) = _TextCellState; + + factory TextCellState.initial(String content) => TextCellState(content: content); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart index 844360fa9b..39badc922a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart @@ -1,7 +1,6 @@ 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 'package:dartz/dartz.dart'; import 'dart:async'; import 'column_service.dart'; import 'data.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart index 3cbe922a58..d28df04c62 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/prelude.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/prelude.dart @@ -5,3 +5,9 @@ export 'grid_service.dart'; export 'data.dart'; export 'column_service.dart'; export 'column_bloc.dart'; +export 'cell_bloc/text_cell_bloc.dart'; +export 'cell_bloc/number_cell_bloc.dart'; +export 'cell_bloc/selection_cell_bloc.dart'; +export 'cell_bloc/date_cell_bloc.dart'; +export 'cell_bloc/checkbox_cell_bloc.dart'; +export 'cell_bloc/cell_service.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart index 9af22beba9..d2852900d9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart @@ -34,7 +34,7 @@ class RowBloc extends Bloc { @freezed abstract class RowEvent with _$RowEvent { - const factory RowEvent.initial(GridRowData data) = _InitialRow; + const factory RowEvent.initial() = _InitialRow; const factory RowEvent.createRow() = _CreateRow; const factory RowEvent.activeRow() = _ActiveRow; const factory RowEvent.disactiveRow() = _DisactiveRow; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart index 53e0bf58aa..249d47011b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart @@ -141,6 +141,7 @@ class _DocumentLeftBarItemState extends State { @override void dispose() { _controller.dispose(); + _focusNode.removeListener(_handleFocusChanged); _focusNode.dispose(); super.dispose(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart index e669a78217..5f8f94e1a2 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart @@ -10,6 +10,7 @@ class GridSize { static double get trailHeaderPadding => 140 * scale; static double get headerContentPadding => 8 * scale; static double get cellContentPadding => 8 * scale; + // static EdgeInsets get headerContentInsets => EdgeInsets.symmetric( horizontal: GridSize.headerContentPadding, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index efe5a0bd3e..754678ef8e 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -1,17 +1,35 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'grid_cell.dart'; +import 'package:flutter/widgets.dart'; +import 'checkbox_cell.dart'; +import 'date_cell.dart'; +import 'number_cell.dart'; +import 'selection_cell.dart'; +import 'text_cell.dart'; -class GridCellBuilder { - static GridCellWidget buildCell(Field? field, Cell? cell) { - if (field == null || cell == null) { - return GridTextCell("123123123"); - } - - switch (field.fieldType) { - case FieldType.RichText: - return GridTextCell(cell.content); - default: - return const BlankCell(); - } +Widget buildGridCell(Field field, Cell? cell) { + switch (field.fieldType) { + case FieldType.Checkbox: + return CheckboxCell(field: field, cell: cell); + case FieldType.DateTime: + return DateCell(field: field, cell: cell); + case FieldType.MultiSelect: + return MultiSelectCell(field: field, cell: cell); + case FieldType.Number: + return NumberCell(field: field, cell: cell); + case FieldType.RichText: + return GridTextCell(field: field, cell: cell); + case FieldType.SingleSelect: + return SingleSelectCell(field: field, cell: cell); + default: + return const BlankCell(); + } +} + +class BlankCell extends StatelessWidget { + const BlankCell({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart new file mode 100644 index 0000000000..d3d2b57735 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart @@ -0,0 +1,47 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class CheckboxCell extends StatefulWidget { + final Field field; + final Cell? cell; + + const CheckboxCell({ + required this.field, + required this.cell, + Key? key, + }) : super(key: key); + + @override + State createState() => _CheckboxCellState(); +} + +class _CheckboxCellState extends State { + late CheckboxCellBloc _cellBloc; + + @override + void initState() { + _cellBloc = getIt(param1: widget.field, param2: widget.cell); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return BlocProvider.value( + value: _cellBloc, + child: BlocBuilder( + builder: (context, state) { + return Container(); + }, + ), + ); + } + + @override + Future dispose() async { + await _cellBloc.close(); + super.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart new file mode 100644 index 0000000000..e1661fdffa --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart @@ -0,0 +1,47 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/date_cell_bloc.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class DateCell extends StatefulWidget { + final Field field; + final Cell? cell; + + const DateCell({ + required this.field, + required this.cell, + Key? key, + }) : super(key: key); + + @override + State createState() => _DateCellState(); +} + +class _DateCellState extends State { + late DateCellBloc _cellBloc; + + @override + void initState() { + _cellBloc = getIt(param1: widget.field, param2: widget.cell); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return BlocProvider.value( + value: _cellBloc, + child: BlocBuilder( + builder: (context, state) { + return Container(); + }, + ), + ); + } + + @override + Future dispose() async { + await _cellBloc.close(); + super.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart deleted file mode 100755 index be04555bd4..0000000000 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart +++ /dev/null @@ -1,80 +0,0 @@ -import 'package:flutter/material.dart'; - -/// The interface of base cell. -abstract class GridCellWidget extends StatelessWidget { - final canSelect = true; - - const GridCellWidget({Key? key}) : super(key: key); -} - -class GridTextCell extends GridCellWidget { - late final TextEditingController _controller; - - GridTextCell(String content, {Key? key}) : super(key: key) { - _controller = TextEditingController(text: content); - } - - @override - Widget build(BuildContext context) { - return TextField( - controller: _controller, - onChanged: (value) {}, - maxLines: 1, - style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), - decoration: const InputDecoration( - contentPadding: EdgeInsets.zero, - border: InputBorder.none, - isDense: true, - ), - ); - } -} - -class DateCell extends GridCellWidget { - final String content; - const DateCell(this.content, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Text(content); - } -} - -class NumberCell extends GridCellWidget { - final String content; - const NumberCell(this.content, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Text(content); - } -} - -class SingleSelectCell extends GridCellWidget { - final String content; - const SingleSelectCell(this.content, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Text(content); - } -} - -class MultiSelectCell extends GridCellWidget { - final String content; - const MultiSelectCell(this.content, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Text(content); - } -} - -class BlankCell extends GridCellWidget { - const BlankCell({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container(); - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index dce4b61d4f..c23bf8f533 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -22,7 +22,7 @@ class _GridRowWidgetState extends State { @override void initState() { - _rowBloc = getIt(param1: widget.data); + _rowBloc = getIt(param1: widget.data)..add(const RowEvent.initial()); super.initState(); } @@ -54,7 +54,7 @@ class _GridRowWidgetState extends State { @override Future dispose() async { - _rowBloc.close(); + await _rowBloc.close(); super.dispose(); } @@ -69,7 +69,7 @@ class _GridRowWidgetState extends State { final cellData = state.data.cellMap[field.id]; return CellContainer( width: field.width.toDouble(), - child: GridCellBuilder.buildCell(field, cellData), + child: buildGridCell(field, cellData), ); }, ).toList(), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart new file mode 100644 index 0000000000..86b9863019 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart @@ -0,0 +1,47 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/number_cell_bloc.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class NumberCell extends StatefulWidget { + final Field field; + final Cell? cell; + + const NumberCell({ + required this.field, + required this.cell, + Key? key, + }) : super(key: key); + + @override + State createState() => _NumberCellState(); +} + +class _NumberCellState extends State { + late NumberCellBloc _cellBloc; + + @override + void initState() { + _cellBloc = getIt(param1: widget.field, param2: widget.cell); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return BlocProvider.value( + value: _cellBloc, + child: BlocBuilder( + builder: (context, state) { + return Container(); + }, + ), + ); + } + + @override + Future dispose() async { + await _cellBloc.close(); + super.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart new file mode 100644 index 0000000000..047cff7475 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart @@ -0,0 +1,75 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter/material.dart'; + +class SingleSelectCell extends StatefulWidget { + final Field field; + final Cell? cell; + + const SingleSelectCell({ + required this.field, + required this.cell, + Key? key, + }) : super(key: key); + + @override + State createState() => _SingleSelectCellState(); +} + +class _SingleSelectCellState extends State { + late SelectionCellBloc _cellBloc; + + @override + void initState() { + _cellBloc = getIt(param1: widget.field, param2: widget.cell); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container(); + } + + @override + Future dispose() async { + await _cellBloc.close(); + super.dispose(); + } +} + +//---------------------------------------------------------------- +class MultiSelectCell extends StatefulWidget { + final Field field; + final Cell? cell; + + const MultiSelectCell({ + required this.field, + required this.cell, + Key? key, + }) : super(key: key); + + @override + State createState() => _MultiSelectCellState(); +} + +class _MultiSelectCellState extends State { + late SelectionCellBloc _cellBloc; + + @override + void initState() { + _cellBloc = getIt(param1: widget.field, param2: widget.cell); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container(); + } + + @override + Future dispose() async { + await _cellBloc.close(); + super.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart new file mode 100644 index 0000000000..7661ddc22f --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -0,0 +1,70 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +/// The interface of base cell. + +class GridTextCell extends StatefulWidget { + final Field field; + final Cell? cell; + + const GridTextCell({ + required this.field, + required this.cell, + Key? key, + }) : super(key: key); + + @override + State createState() => _GridTextCellState(); +} + +class _GridTextCellState extends State { + late TextEditingController _controller; + final _focusNode = FocusNode(); + late TextCellBloc _cellBloc; + + @override + void initState() { + _cellBloc = getIt(param1: widget.field, param2: widget.cell); + _controller = TextEditingController(text: _cellBloc.state.content); + _focusNode.addListener(_focusChanged); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return BlocProvider.value( + value: _cellBloc, + child: BlocBuilder( + builder: (context, state) { + return TextField( + controller: _controller, + focusNode: _focusNode, + onChanged: (value) {}, + maxLines: 1, + style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), + decoration: const InputDecoration( + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + isDense: true, + ), + ); + }, + ), + ); + } + + @override + Future dispose() async { + await _cellBloc.close(); + _focusNode.removeListener(_focusChanged); + _focusNode.dispose(); + super.dispose(); + } + + void _focusChanged() { + _cellBloc.add(TextCellEvent.updateText(_controller.text)); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index d3cf4a5255..83d24535f4 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -43,7 +43,7 @@ class GridHeader extends StatelessWidget { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt(param1: fields), + create: (context) => getIt(param1: fields)..add(const ColumnEvent.initial()), child: BlocBuilder( builder: (context, state) { final headers = state.fields diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index eb17b1f35e..087d5c51cd 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,6 +1,8 @@ use crate::manager::GridManager; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedRow}; +use flowy_grid_data_model::entities::{ + Cell, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedRow, +}; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -47,3 +49,14 @@ pub(crate) async fn create_row_handler( let _ = editor.create_empty_row().await?; Ok(()) } + +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn update_cell_handler( + data: Data, + manager: AppData>, +) -> Result<(), FlowyError> { + let cell: Cell = data.into_inner(); + let editor = manager.get_grid_editor(id.as_ref())?; + let _ = editor.create_empty_row().await?; + Ok(()) +} diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index f171e27826..773e632191 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -11,7 +11,8 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::GetGridData, get_grid_data_handler) .event(GridEvent::GetRows, get_rows_handler) .event(GridEvent::GetFields, get_fields_handler) - .event(GridEvent::CreateRow, create_row_handler); + .event(GridEvent::CreateRow, create_row_handler) + .event(GridEvent::UpdateCell, update_cell_handler); module } @@ -30,4 +31,7 @@ pub enum GridEvent { #[event(input = "GridId")] CreateRow = 3, + + #[event(input = "Cell")] + UpdateCell = 4, } 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 9512e59b26..096735c07d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -15,6 +15,7 @@ use lib_infra::future::FutureResult; use lib_infra::uuid; use lib_ot::core::PlainTextAttributes; +use dashmap::mapref::one::Ref; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; use std::sync::Arc; @@ -28,6 +29,7 @@ pub struct ClientGridEditor { kv_persistence: Arc, field_map: DashMap, + cell_map: DashMap, } impl ClientGridEditor { @@ -44,6 +46,7 @@ impl ClientGridEditor { let rev_manager = Arc::new(rev_manager); let field_map = load_all_fields(&grid_pad, &kv_persistence).await?; let grid_pad = Arc::new(RwLock::new(grid_pad)); + let cell_map = DashMap::new(); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), @@ -52,17 +55,20 @@ impl ClientGridEditor { rev_manager, kv_persistence, field_map, + cell_map, })) } pub async fn create_empty_row(&self) -> FlowyResult<()> { let row = RawRow::new(&uuid(), &self.grid_id, vec![]); + self.cell_map.insert(row.id.clone(), row.clone()); self.create_row(row).await?; Ok(()) } async fn create_row(&self, row: RawRow) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.create_row(&row)?)).await?; + self.cell_map.insert(row.id.clone(), row.clone()); let _ = self.kv_persistence.set(row)?; Ok(()) } @@ -73,6 +79,13 @@ impl ClientGridEditor { Ok(()) } + // pub async fn update_row(&self, cell: Cell) -> FlowyResult<()> { + // match self.cell_map.get(&cell.id) { + // None => Err(FlowyError::internal().context(format!("Can't find cell with id: {}", cell.id))), + // Some(raw_cell) => {} + // } + // } + pub async fn create_field(&mut self, field: Field) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.create_field(&field)?)).await?; let _ = self.kv_persistence.set(field)?; @@ -99,6 +112,7 @@ impl ClientGridEditor { tracing::error!("Can't find the field with {}", field_id); return None; } + self.cell_map.insert(raw_cell.id.clone(), raw_cell.clone()); let field = some_field.unwrap(); match stringify_deserialize(raw_cell.data, field.value()) { From e45be3b81e0b60ea089020322b8b2564b9b164f1 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 10 Mar 2022 12:01:31 +0800 Subject: [PATCH 07/28] chore: add grid meta --- .../application/grid/grid_service.dart | 9 +- .../dart_event/flowy-grid/dart_event.dart | 17 + .../flowy-grid-data-model/grid.pb.dart | 682 +---- .../flowy-grid-data-model/grid.pbenum.dart | 27 - .../flowy-grid-data-model/grid.pbjson.dart | 138 +- .../flowy-grid-data-model/meta.pb.dart | 584 +++++ .../flowy-grid-data-model/meta.pbenum.dart | 34 + .../flowy-grid-data-model/meta.pbjson.dart | 125 + .../flowy-grid-data-model/meta.pbserver.dart | 9 + .../flowy-grid-data-model/protobuf.dart | 1 + .../protobuf/flowy-grid/event_map.pbenum.dart | 2 + .../protobuf/flowy-grid/event_map.pbjson.dart | 3 +- .../rust-lib/flowy-grid/src/event_handler.rs | 4 +- frontend/rust-lib/flowy-grid/src/manager.rs | 14 +- .../src/protobuf/model/event_map.rs | 7 +- .../src/protobuf/proto/event_map.proto | 1 + .../flowy-grid/src/services/grid_builder.rs | 29 +- .../flowy-grid/src/services/grid_editor.rs | 60 +- .../flowy-grid/src/services/kv_persistence.rs | 36 +- .../src/client_grid/grid_pad.rs | 110 +- .../src/entities/grid.rs | 272 +- .../src/entities/meta.rs | 215 ++ .../flowy-grid-data-model/src/entities/mod.rs | 2 + .../src/protobuf/model/grid.rs | 2329 ++--------------- .../src/protobuf/model/meta.rs | 2040 +++++++++++++++ .../src/protobuf/model/mod.rs | 3 + .../src/protobuf/proto/grid.proto | 58 +- .../src/protobuf/proto/meta.proto | 50 + .../flowy-grid-data-model/tests/serde_test.rs | 50 +- 29 files changed, 3529 insertions(+), 3382 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbserver.dart create mode 100644 shared-lib/flowy-grid-data-model/src/entities/meta.rs create mode 100644 shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs create mode 100644 shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index 5f7f56fb45..e519b0a90d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -16,18 +16,17 @@ class GridService { return GridEventCreateRow(GridId(value: gridId)).send(); } - Future> getRows({required String gridId, required RepeatedRowOrder rowOrders}) { + Future> getRows({required String gridId, required List rowOrders}) { final payload = QueryRowPayload.create() ..gridId = gridId - ..rowOrders = rowOrders; + ..rowOrders = RepeatedRowOrder(items: rowOrders); return GridEventGetRows(payload).send(); } - Future> getFields( - {required String gridId, required RepeatedFieldOrder fieldOrders}) { + Future> getFields({required String gridId, required List fieldOrders}) { final payload = QueryFieldPayload.create() ..gridId = gridId - ..fieldOrders = fieldOrders; + ..fieldOrders = RepeatedFieldOrder(items: fieldOrders); return GridEventGetFields(payload).send(); } } 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 b62b350f5e..4aeda8ede9 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 @@ -69,3 +69,20 @@ class GridEventCreateRow { } } +class GridEventUpdateCell { + Cell request; + GridEventUpdateCell(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.UpdateCell.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (bytes) => left(unit), + (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 6fd298b16d..c853bb867b 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 @@ -9,33 +9,29 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; -import 'grid.pbenum.dart'; - -export 'grid.pbenum.dart'; - class Grid extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Grid', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', subBuilder: RepeatedFieldOrder.create) - ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', subBuilder: RepeatedRowOrder.create) + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', $pb.PbFieldType.PM, subBuilder: FieldOrder.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', $pb.PbFieldType.PM, subBuilder: RowOrder.create) ..hasRequiredFields = false ; Grid._() : super(); factory Grid({ $core.String? id, - RepeatedFieldOrder? fieldOrders, - RepeatedRowOrder? rowOrders, + $core.Iterable? fieldOrders, + $core.Iterable? rowOrders, }) { final _result = create(); if (id != null) { _result.id = id; } if (fieldOrders != null) { - _result.fieldOrders = fieldOrders; + _result.fieldOrders.addAll(fieldOrders); } if (rowOrders != null) { - _result.rowOrders = rowOrders; + _result.rowOrders.addAll(rowOrders); } return _result; } @@ -70,47 +66,26 @@ class Grid extends $pb.GeneratedMessage { void clearId() => clearField(1); @$pb.TagNumber(2) - RepeatedFieldOrder get fieldOrders => $_getN(1); - @$pb.TagNumber(2) - set fieldOrders(RepeatedFieldOrder v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasFieldOrders() => $_has(1); - @$pb.TagNumber(2) - void clearFieldOrders() => clearField(2); - @$pb.TagNumber(2) - RepeatedFieldOrder ensureFieldOrders() => $_ensure(1); + $core.List get fieldOrders => $_getList(1); @$pb.TagNumber(3) - RepeatedRowOrder get rowOrders => $_getN(2); - @$pb.TagNumber(3) - set rowOrders(RepeatedRowOrder v) { setField(3, v); } - @$pb.TagNumber(3) - $core.bool hasRowOrders() => $_has(2); - @$pb.TagNumber(3) - void clearRowOrders() => clearField(3); - @$pb.TagNumber(3) - RepeatedRowOrder ensureRowOrders() => $_ensure(2); + $core.List get rowOrders => $_getList(2); } class FieldOrder extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldOrder', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..hasRequiredFields = false ; FieldOrder._() : super(); factory FieldOrder({ $core.String? fieldId, - $core.bool? visibility, }) { final _result = create(); if (fieldId != null) { _result.fieldId = fieldId; } - if (visibility != null) { - _result.visibility = visibility; - } return _result; } factory FieldOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -142,15 +117,6 @@ class FieldOrder extends $pb.GeneratedMessage { $core.bool hasFieldId() => $_has(0); @$pb.TagNumber(1) void clearFieldId() => clearField(1); - - @$pb.TagNumber(2) - $core.bool get visibility => $_getBF(1); - @$pb.TagNumber(2) - set visibility($core.bool v) { $_setBool(1, v); } - @$pb.TagNumber(2) - $core.bool hasVisibility() => $_has(1); - @$pb.TagNumber(2) - void clearVisibility() => clearField(2); } class RepeatedFieldOrder extends $pb.GeneratedMessage { @@ -194,265 +160,20 @@ class RepeatedFieldOrder extends $pb.GeneratedMessage { $core.List get items => $_getList(0); } -class Field extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Field', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') - ..e(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values) - ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') - ..a<$core.int>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) - ..aOM(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', subBuilder: AnyData.create) - ..hasRequiredFields = false - ; - - Field._() : super(); - factory Field({ - $core.String? id, - $core.String? name, - $core.String? desc, - FieldType? fieldType, - $core.bool? frozen, - $core.int? width, - AnyData? typeOptions, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (name != null) { - _result.name = name; - } - if (desc != null) { - _result.desc = desc; - } - if (fieldType != null) { - _result.fieldType = fieldType; - } - if (frozen != null) { - _result.frozen = frozen; - } - if (width != null) { - _result.width = width; - } - if (typeOptions != null) { - _result.typeOptions = typeOptions; - } - return _result; - } - factory Field.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Field.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Field clone() => Field()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Field copyWith(void Function(Field) updates) => super.copyWith((message) => updates(message as Field)) as Field; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Field create() => Field._(); - Field createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static Field getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static Field? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get name => $_getSZ(1); - @$pb.TagNumber(2) - set name($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasName() => $_has(1); - @$pb.TagNumber(2) - void clearName() => clearField(2); - - @$pb.TagNumber(3) - $core.String get desc => $_getSZ(2); - @$pb.TagNumber(3) - set desc($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasDesc() => $_has(2); - @$pb.TagNumber(3) - void clearDesc() => clearField(3); - - @$pb.TagNumber(4) - FieldType get fieldType => $_getN(3); - @$pb.TagNumber(4) - set fieldType(FieldType v) { setField(4, v); } - @$pb.TagNumber(4) - $core.bool hasFieldType() => $_has(3); - @$pb.TagNumber(4) - void clearFieldType() => clearField(4); - - @$pb.TagNumber(5) - $core.bool get frozen => $_getBF(4); - @$pb.TagNumber(5) - set frozen($core.bool v) { $_setBool(4, v); } - @$pb.TagNumber(5) - $core.bool hasFrozen() => $_has(4); - @$pb.TagNumber(5) - void clearFrozen() => clearField(5); - - @$pb.TagNumber(6) - $core.int get width => $_getIZ(5); - @$pb.TagNumber(6) - set width($core.int v) { $_setSignedInt32(5, v); } - @$pb.TagNumber(6) - $core.bool hasWidth() => $_has(5); - @$pb.TagNumber(6) - void clearWidth() => clearField(6); - - @$pb.TagNumber(7) - AnyData get typeOptions => $_getN(6); - @$pb.TagNumber(7) - set typeOptions(AnyData v) { setField(7, v); } - @$pb.TagNumber(7) - $core.bool hasTypeOptions() => $_has(6); - @$pb.TagNumber(7) - void clearTypeOptions() => clearField(7); - @$pb.TagNumber(7) - AnyData ensureTypeOptions() => $_ensure(6); -} - -class RepeatedField extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedField', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Field.create) - ..hasRequiredFields = false - ; - - RepeatedField._() : super(); - factory RepeatedField({ - $core.Iterable? items, - }) { - final _result = create(); - if (items != null) { - _result.items.addAll(items); - } - return _result; - } - factory RepeatedField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RepeatedField.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RepeatedField clone() => RepeatedField()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RepeatedField copyWith(void Function(RepeatedField) updates) => super.copyWith((message) => updates(message as RepeatedField)) as RepeatedField; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RepeatedField create() => RepeatedField._(); - RepeatedField createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RepeatedField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RepeatedField? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get items => $_getList(0); -} - -class AnyData extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AnyData', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeId') - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value', $pb.PbFieldType.OY) - ..hasRequiredFields = false - ; - - AnyData._() : super(); - factory AnyData({ - $core.String? typeId, - $core.List<$core.int>? value, - }) { - final _result = create(); - if (typeId != null) { - _result.typeId = typeId; - } - if (value != null) { - _result.value = value; - } - return _result; - } - factory AnyData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory AnyData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - AnyData clone() => AnyData()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - AnyData copyWith(void Function(AnyData) updates) => super.copyWith((message) => updates(message as AnyData)) as AnyData; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static AnyData create() => AnyData._(); - AnyData createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static AnyData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static AnyData? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get typeId => $_getSZ(0); - @$pb.TagNumber(1) - set typeId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasTypeId() => $_has(0); - @$pb.TagNumber(1) - void clearTypeId() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.int> get value => $_getN(1); - @$pb.TagNumber(2) - set value($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasValue() => $_has(1); - @$pb.TagNumber(2) - void clearValue() => clearField(2); -} - class RowOrder extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowOrder', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..aOB(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') ..hasRequiredFields = false ; RowOrder._() : super(); factory RowOrder({ - $core.String? gridId, $core.String? rowId, - $core.bool? visibility, }) { final _result = create(); - if (gridId != null) { - _result.gridId = gridId; - } if (rowId != null) { _result.rowId = rowId; } - if (visibility != null) { - _result.visibility = visibility; - } return _result; } factory RowOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -477,31 +198,13 @@ class RowOrder extends $pb.GeneratedMessage { static RowOrder? _defaultInstance; @$pb.TagNumber(1) - $core.String get gridId => $_getSZ(0); + $core.String get rowId => $_getSZ(0); @$pb.TagNumber(1) - set gridId($core.String v) { $_setString(0, v); } + set rowId($core.String v) { $_setString(0, v); } @$pb.TagNumber(1) - $core.bool hasGridId() => $_has(0); + $core.bool hasRowId() => $_has(0); @$pb.TagNumber(1) - void clearGridId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get rowId => $_getSZ(1); - @$pb.TagNumber(2) - set rowId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasRowId() => $_has(1); - @$pb.TagNumber(2) - void clearRowId() => clearField(2); - - @$pb.TagNumber(3) - $core.bool get visibility => $_getBF(2); - @$pb.TagNumber(3) - set visibility($core.bool v) { $_setBool(2, v); } - @$pb.TagNumber(3) - $core.bool hasVisibility() => $_has(2); - @$pb.TagNumber(3) - void clearVisibility() => clearField(3); + void clearRowId() => clearField(1); } class RepeatedRowOrder extends $pb.GeneratedMessage { @@ -545,235 +248,6 @@ class RepeatedRowOrder extends $pb.GeneratedMessage { $core.List get items => $_getList(0); } -class RawRow extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RawRow', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..m<$core.String, RawCell>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'RawRow.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: RawCell.create) - ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) - ..hasRequiredFields = false - ; - - RawRow._() : super(); - factory RawRow({ - $core.String? id, - $core.String? gridId, - $core.Map<$core.String, RawCell>? cellByFieldId, - $core.int? height, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (gridId != null) { - _result.gridId = gridId; - } - if (cellByFieldId != null) { - _result.cellByFieldId.addAll(cellByFieldId); - } - if (height != null) { - _result.height = height; - } - return _result; - } - factory RawRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RawRow.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RawRow clone() => RawRow()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RawRow copyWith(void Function(RawRow) updates) => super.copyWith((message) => updates(message as RawRow)) as RawRow; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RawRow create() => RawRow._(); - RawRow createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RawRow getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RawRow? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get gridId => $_getSZ(1); - @$pb.TagNumber(2) - set gridId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasGridId() => $_has(1); - @$pb.TagNumber(2) - void clearGridId() => clearField(2); - - @$pb.TagNumber(3) - $core.Map<$core.String, RawCell> get cellByFieldId => $_getMap(2); - - @$pb.TagNumber(4) - $core.int get height => $_getIZ(3); - @$pb.TagNumber(4) - set height($core.int v) { $_setSignedInt32(3, v); } - @$pb.TagNumber(4) - $core.bool hasHeight() => $_has(3); - @$pb.TagNumber(4) - void clearHeight() => clearField(4); -} - -class RawCell extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RawCell', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOM(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: AnyData.create) - ..a<$core.int>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) - ..hasRequiredFields = false - ; - - RawCell._() : super(); - factory RawCell({ - $core.String? id, - $core.String? rowId, - $core.String? fieldId, - AnyData? data, - $core.int? height, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (rowId != null) { - _result.rowId = rowId; - } - if (fieldId != null) { - _result.fieldId = fieldId; - } - if (data != null) { - _result.data = data; - } - if (height != null) { - _result.height = height; - } - return _result; - } - factory RawCell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RawCell.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RawCell clone() => RawCell()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RawCell copyWith(void Function(RawCell) updates) => super.copyWith((message) => updates(message as RawCell)) as RawCell; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RawCell create() => RawCell._(); - RawCell createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RawCell getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RawCell? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get rowId => $_getSZ(1); - @$pb.TagNumber(2) - set rowId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasRowId() => $_has(1); - @$pb.TagNumber(2) - void clearRowId() => clearField(2); - - @$pb.TagNumber(3) - $core.String get fieldId => $_getSZ(2); - @$pb.TagNumber(3) - set fieldId($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasFieldId() => $_has(2); - @$pb.TagNumber(3) - void clearFieldId() => clearField(3); - - @$pb.TagNumber(4) - AnyData get data => $_getN(3); - @$pb.TagNumber(4) - set data(AnyData v) { setField(4, v); } - @$pb.TagNumber(4) - $core.bool hasData() => $_has(3); - @$pb.TagNumber(4) - void clearData() => clearField(4); - @$pb.TagNumber(4) - AnyData ensureData() => $_ensure(3); - - @$pb.TagNumber(5) - $core.int get height => $_getIZ(4); - @$pb.TagNumber(5) - set height($core.int v) { $_setSignedInt32(4, v); } - @$pb.TagNumber(5) - $core.bool hasHeight() => $_has(4); - @$pb.TagNumber(5) - void clearHeight() => clearField(5); -} - -class RepeatedRow extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedRow', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Row.create) - ..hasRequiredFields = false - ; - - RepeatedRow._() : super(); - factory RepeatedRow({ - $core.Iterable? items, - }) { - final _result = create(); - if (items != null) { - _result.items.addAll(items); - } - return _result; - } - factory RepeatedRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RepeatedRow.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RepeatedRow clone() => RepeatedRow()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RepeatedRow copyWith(void Function(RepeatedRow) updates) => super.copyWith((message) => updates(message as RepeatedRow)) as RepeatedRow; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RepeatedRow create() => RepeatedRow._(); - RepeatedRow createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RepeatedRow getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RepeatedRow? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get items => $_getList(0); -} - class Row extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Row', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') @@ -843,6 +317,47 @@ class Row extends $pb.GeneratedMessage { void clearHeight() => clearField(3); } +class RepeatedRow extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedRow', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Row.create) + ..hasRequiredFields = false + ; + + RepeatedRow._() : super(); + factory RepeatedRow({ + $core.Iterable? items, + }) { + final _result = create(); + if (items != null) { + _result.items.addAll(items); + } + return _result; + } + factory RepeatedRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedRow.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RepeatedRow clone() => RepeatedRow()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RepeatedRow copyWith(void Function(RepeatedRow) updates) => super.copyWith((message) => updates(message as RepeatedRow)) as RepeatedRow; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RepeatedRow create() => RepeatedRow._(); + RepeatedRow createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RepeatedRow getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedRow? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get items => $_getList(0); +} + 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') ? '' : 'id') @@ -918,95 +433,6 @@ class Cell extends $pb.GeneratedMessage { void clearContent() => clearField(3); } -class CellChangeset extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellChangeset', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') - ..hasRequiredFields = false - ; - - CellChangeset._() : super(); - factory CellChangeset({ - $core.String? id, - $core.String? rowId, - $core.String? fieldId, - $core.String? data, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (rowId != null) { - _result.rowId = rowId; - } - if (fieldId != null) { - _result.fieldId = fieldId; - } - if (data != null) { - _result.data = data; - } - return _result; - } - factory CellChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CellChangeset.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - CellChangeset clone() => CellChangeset()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CellChangeset copyWith(void Function(CellChangeset) updates) => super.copyWith((message) => updates(message as CellChangeset)) as CellChangeset; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CellChangeset create() => CellChangeset._(); - CellChangeset createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static CellChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static CellChangeset? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get rowId => $_getSZ(1); - @$pb.TagNumber(2) - set rowId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasRowId() => $_has(1); - @$pb.TagNumber(2) - void clearRowId() => clearField(2); - - @$pb.TagNumber(3) - $core.String get fieldId => $_getSZ(2); - @$pb.TagNumber(3) - set fieldId($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasFieldId() => $_has(2); - @$pb.TagNumber(3) - void clearFieldId() => clearField(3); - - @$pb.TagNumber(4) - $core.String get data => $_getSZ(3); - @$pb.TagNumber(4) - set data($core.String v) { $_setString(3, v); } - @$pb.TagNumber(4) - $core.bool hasData() => $_has(3); - @$pb.TagNumber(4) - void clearData() => clearField(4); -} - class CreateGridPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateGridPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart index 661b26532c..0ea2223329 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart @@ -5,30 +5,3 @@ // @dart = 2.12 // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields -// ignore_for_file: UNDEFINED_SHOWN_NAME -import 'dart:core' as $core; -import 'package:protobuf/protobuf.dart' as $pb; - -class FieldType extends $pb.ProtobufEnum { - static const FieldType RichText = FieldType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RichText'); - static const FieldType Number = FieldType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Number'); - static const FieldType DateTime = FieldType._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DateTime'); - static const FieldType SingleSelect = FieldType._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SingleSelect'); - static const FieldType MultiSelect = FieldType._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MultiSelect'); - static const FieldType Checkbox = FieldType._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Checkbox'); - - static const $core.List values = [ - RichText, - Number, - DateTime, - SingleSelect, - MultiSelect, - Checkbox, - ]; - - static final $core.Map<$core.int, FieldType> _byValue = $pb.ProtobufEnum.initByValue(values); - static FieldType? valueOf($core.int value) => _byValue[value]; - - const FieldType._($core.int v, $core.String n) : super(v, n); -} - 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 81257592ac..96bfd55dfd 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 @@ -8,44 +8,28 @@ import 'dart:core' as $core; import 'dart:convert' as $convert; import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use fieldTypeDescriptor instead') -const FieldType$json = const { - '1': 'FieldType', - '2': const [ - const {'1': 'RichText', '2': 0}, - const {'1': 'Number', '2': 1}, - const {'1': 'DateTime', '2': 2}, - const {'1': 'SingleSelect', '2': 3}, - const {'1': 'MultiSelect', '2': 4}, - const {'1': 'Checkbox', '2': 5}, - ], -}; - -/// Descriptor for `FieldType`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List fieldTypeDescriptor = $convert.base64Decode('CglGaWVsZFR5cGUSDAoIUmljaFRleHQQABIKCgZOdW1iZXIQARIMCghEYXRlVGltZRACEhAKDFNpbmdsZVNlbGVjdBADEg8KC011bHRpU2VsZWN0EAQSDAoIQ2hlY2tib3gQBQ=='); @$core.Deprecated('Use gridDescriptor instead') const Grid$json = const { '1': 'Grid', '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'field_orders', '3': 2, '4': 1, '5': 11, '6': '.RepeatedFieldOrder', '10': 'fieldOrders'}, - const {'1': 'row_orders', '3': 3, '4': 1, '5': 11, '6': '.RepeatedRowOrder', '10': 'rowOrders'}, + const {'1': 'field_orders', '3': 2, '4': 3, '5': 11, '6': '.FieldOrder', '10': 'fieldOrders'}, + const {'1': 'row_orders', '3': 3, '4': 3, '5': 11, '6': '.RowOrder', '10': 'rowOrders'}, ], }; /// Descriptor for `Grid`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBI2CgxmaWVsZF9vcmRlcnMYAiABKAsyEy5SZXBlYXRlZEZpZWxkT3JkZXJSC2ZpZWxkT3JkZXJzEjAKCnJvd19vcmRlcnMYAyABKAsyES5SZXBlYXRlZFJvd09yZGVyUglyb3dPcmRlcnM='); +final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxIoCgpyb3dfb3JkZXJzGAMgAygLMgkuUm93T3JkZXJSCXJvd09yZGVycw=='); @$core.Deprecated('Use fieldOrderDescriptor instead') const FieldOrder$json = const { '1': 'FieldOrder', '2': const [ const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'visibility', '3': 2, '4': 1, '5': 8, '10': 'visibility'}, ], }; /// Descriptor for `FieldOrder`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEh4KCnZpc2liaWxpdHkYAiABKAhSCnZpc2liaWxpdHk='); +final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElk'); @$core.Deprecated('Use repeatedFieldOrderDescriptor instead') const RepeatedFieldOrder$json = const { '1': 'RepeatedFieldOrder', @@ -56,55 +40,16 @@ const RepeatedFieldOrder$json = const { /// Descriptor for `RepeatedFieldOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List repeatedFieldOrderDescriptor = $convert.base64Decode('ChJSZXBlYXRlZEZpZWxkT3JkZXISIQoFaXRlbXMYASADKAsyCy5GaWVsZE9yZGVyUgVpdGVtcw=='); -@$core.Deprecated('Use fieldDescriptor instead') -const Field$json = const { - '1': 'Field', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, - const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'}, - const {'1': 'field_type', '3': 4, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'}, - const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'}, - const {'1': 'width', '3': 6, '4': 1, '5': 5, '10': 'width'}, - const {'1': 'type_options', '3': 7, '4': 1, '5': 11, '6': '.AnyData', '10': 'typeOptions'}, - ], -}; - -/// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIUCgV3aWR0aBgGIAEoBVIFd2lkdGgSKwoMdHlwZV9vcHRpb25zGAcgASgLMgguQW55RGF0YVILdHlwZU9wdGlvbnM='); -@$core.Deprecated('Use repeatedFieldDescriptor instead') -const RepeatedField$json = const { - '1': 'RepeatedField', - '2': const [ - const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Field', '10': 'items'}, - ], -}; - -/// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z'); -@$core.Deprecated('Use anyDataDescriptor instead') -const AnyData$json = const { - '1': 'AnyData', - '2': const [ - const {'1': 'type_id', '3': 1, '4': 1, '5': 9, '10': 'typeId'}, - const {'1': 'value', '3': 2, '4': 1, '5': 12, '10': 'value'}, - ], -}; - -/// Descriptor for `AnyData`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List anyDataDescriptor = $convert.base64Decode('CgdBbnlEYXRhEhcKB3R5cGVfaWQYASABKAlSBnR5cGVJZBIUCgV2YWx1ZRgCIAEoDFIFdmFsdWU='); @$core.Deprecated('Use rowOrderDescriptor instead') const RowOrder$json = const { '1': 'RowOrder', '2': const [ - const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, - const {'1': 'visibility', '3': 3, '4': 1, '5': 8, '10': 'visibility'}, + const {'1': 'row_id', '3': 1, '4': 1, '5': 9, '10': 'rowId'}, ], }; /// Descriptor for `RowOrder`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rowOrderDescriptor = $convert.base64Decode('CghSb3dPcmRlchIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIeCgp2aXNpYmlsaXR5GAMgASgIUgp2aXNpYmlsaXR5'); +final $typed_data.Uint8List rowOrderDescriptor = $convert.base64Decode('CghSb3dPcmRlchIVCgZyb3dfaWQYASABKAlSBXJvd0lk'); @$core.Deprecated('Use repeatedRowOrderDescriptor instead') const RepeatedRowOrder$json = const { '1': 'RepeatedRowOrder', @@ -115,54 +60,6 @@ const RepeatedRowOrder$json = const { /// Descriptor for `RepeatedRowOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List repeatedRowOrderDescriptor = $convert.base64Decode('ChBSZXBlYXRlZFJvd09yZGVyEh8KBWl0ZW1zGAEgAygLMgkuUm93T3JkZXJSBWl0ZW1z'); -@$core.Deprecated('Use rawRowDescriptor instead') -const RawRow$json = const { - '1': 'RawRow', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'cell_by_field_id', '3': 3, '4': 3, '5': 11, '6': '.RawRow.CellByFieldIdEntry', '10': 'cellByFieldId'}, - const {'1': 'height', '3': 4, '4': 1, '5': 5, '10': 'height'}, - ], - '3': const [RawRow_CellByFieldIdEntry$json], -}; - -@$core.Deprecated('Use rawRowDescriptor instead') -const RawRow_CellByFieldIdEntry$json = const { - '1': 'CellByFieldIdEntry', - '2': const [ - const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'}, - const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.RawCell', '10': 'value'}, - ], - '7': const {'7': true}, -}; - -/// Descriptor for `RawRow`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rawRowDescriptor = $convert.base64Decode('CgZSYXdSb3cSDgoCaWQYASABKAlSAmlkEhcKB2dyaWRfaWQYAiABKAlSBmdyaWRJZBJDChBjZWxsX2J5X2ZpZWxkX2lkGAMgAygLMhouUmF3Um93LkNlbGxCeUZpZWxkSWRFbnRyeVINY2VsbEJ5RmllbGRJZBIWCgZoZWlnaHQYBCABKAVSBmhlaWdodBpKChJDZWxsQnlGaWVsZElkRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSHgoFdmFsdWUYAiABKAsyCC5SYXdDZWxsUgV2YWx1ZToCOAE='); -@$core.Deprecated('Use rawCellDescriptor instead') -const RawCell$json = const { - '1': 'RawCell', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, - const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'data', '3': 4, '4': 1, '5': 11, '6': '.AnyData', '10': 'data'}, - const {'1': 'height', '3': 5, '4': 1, '5': 5, '10': 'height'}, - ], -}; - -/// Descriptor for `RawCell`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rawCellDescriptor = $convert.base64Decode('CgdSYXdDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhwKBGRhdGEYBCABKAsyCC5BbnlEYXRhUgRkYXRhEhYKBmhlaWdodBgFIAEoBVIGaGVpZ2h0'); -@$core.Deprecated('Use repeatedRowDescriptor instead') -const RepeatedRow$json = const { - '1': 'RepeatedRow', - '2': const [ - const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Row', '10': 'items'}, - ], -}; - -/// Descriptor for `RepeatedRow`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List repeatedRowDescriptor = $convert.base64Decode('CgtSZXBlYXRlZFJvdxIaCgVpdGVtcxgBIAMoCzIELlJvd1IFaXRlbXM='); @$core.Deprecated('Use rowDescriptor instead') const Row$json = const { '1': 'Row', @@ -186,6 +83,16 @@ const Row_CellByFieldIdEntry$json = const { /// Descriptor for `Row`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List rowDescriptor = $convert.base64Decode('CgNSb3cSDgoCaWQYASABKAlSAmlkEkAKEGNlbGxfYnlfZmllbGRfaWQYAiADKAsyFy5Sb3cuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgDIAEoBVIGaGVpZ2h0GkcKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIbCgV2YWx1ZRgCIAEoCzIFLkNlbGxSBXZhbHVlOgI4AQ=='); +@$core.Deprecated('Use repeatedRowDescriptor instead') +const RepeatedRow$json = const { + '1': 'RepeatedRow', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Row', '10': 'items'}, + ], +}; + +/// Descriptor for `RepeatedRow`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedRowDescriptor = $convert.base64Decode('CgtSZXBlYXRlZFJvdxIaCgVpdGVtcxgBIAMoCzIELlJvd1IFaXRlbXM='); @$core.Deprecated('Use cellDescriptor instead') const Cell$json = const { '1': 'Cell', @@ -198,19 +105,6 @@ const Cell$json = const { /// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEg4KAmlkGAEgASgJUgJpZBIZCghmaWVsZF9pZBgCIAEoCVIHZmllbGRJZBIYCgdjb250ZW50GAMgASgJUgdjb250ZW50'); -@$core.Deprecated('Use cellChangesetDescriptor instead') -const CellChangeset$json = const { - '1': 'CellChangeset', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, - const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'data', '3': 4, '4': 1, '5': 9, '10': 'data'}, - ], -}; - -/// Descriptor for `CellChangeset`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellChangesetDescriptor = $convert.base64Decode('Cg1DZWxsQ2hhbmdlc2V0Eg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhIKBGRhdGEYBCABKAlSBGRhdGE='); @$core.Deprecated('Use createGridPayloadDescriptor instead') const CreateGridPayload$json = const { '1': 'CreateGridPayload', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart new file mode 100644 index 0000000000..11370c1fd2 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -0,0 +1,584 @@ +/// +// Generated code. Do not modify. +// source: meta.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'meta.pbenum.dart'; + +export 'meta.pbenum.dart'; + +class GridMeta extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: Field.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) + ..hasRequiredFields = false + ; + + GridMeta._() : super(); + factory GridMeta({ + $core.String? gridId, + $core.Iterable? fields, + $core.Iterable? rows, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (fields != null) { + _result.fields.addAll(fields); + } + if (rows != null) { + _result.rows.addAll(rows); + } + return _result; + } + factory GridMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + GridMeta clone() => GridMeta()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridMeta copyWith(void Function(GridMeta) updates) => super.copyWith((message) => updates(message as GridMeta)) as GridMeta; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridMeta create() => GridMeta._(); + GridMeta createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridMeta? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get gridId => $_getSZ(0); + @$pb.TagNumber(1) + set gridId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasGridId() => $_has(0); + @$pb.TagNumber(1) + void clearGridId() => clearField(1); + + @$pb.TagNumber(2) + $core.List get fields => $_getList(1); + + @$pb.TagNumber(3) + $core.List get rows => $_getList(2); +} + +class GridBlock extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) + ..hasRequiredFields = false + ; + + GridBlock._() : super(); + factory GridBlock({ + $core.String? id, + $core.Iterable? rows, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (rows != null) { + _result.rows.addAll(rows); + } + return _result; + } + factory GridBlock.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlock.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + GridBlock clone() => GridBlock()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridBlock copyWith(void Function(GridBlock) updates) => super.copyWith((message) => updates(message as GridBlock)) as GridBlock; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridBlock create() => GridBlock._(); + GridBlock createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridBlock getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlock? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.List get rows => $_getList(1); +} + +class Field extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Field', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') + ..e(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values) + ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') + ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') + ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) + ..aOM(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', subBuilder: AnyData.create) + ..hasRequiredFields = false + ; + + Field._() : super(); + factory Field({ + $core.String? id, + $core.String? name, + $core.String? desc, + FieldType? fieldType, + $core.bool? frozen, + $core.bool? visibility, + $core.int? width, + AnyData? typeOptions, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (name != null) { + _result.name = name; + } + if (desc != null) { + _result.desc = desc; + } + if (fieldType != null) { + _result.fieldType = fieldType; + } + if (frozen != null) { + _result.frozen = frozen; + } + if (visibility != null) { + _result.visibility = visibility; + } + if (width != null) { + _result.width = width; + } + if (typeOptions != null) { + _result.typeOptions = typeOptions; + } + return _result; + } + factory Field.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Field.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Field clone() => Field()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Field copyWith(void Function(Field) updates) => super.copyWith((message) => updates(message as Field)) as Field; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Field create() => Field._(); + Field createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Field getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Field? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get name => $_getSZ(1); + @$pb.TagNumber(2) + set name($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasName() => $_has(1); + @$pb.TagNumber(2) + void clearName() => clearField(2); + + @$pb.TagNumber(3) + $core.String get desc => $_getSZ(2); + @$pb.TagNumber(3) + set desc($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasDesc() => $_has(2); + @$pb.TagNumber(3) + void clearDesc() => clearField(3); + + @$pb.TagNumber(4) + FieldType get fieldType => $_getN(3); + @$pb.TagNumber(4) + set fieldType(FieldType v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasFieldType() => $_has(3); + @$pb.TagNumber(4) + void clearFieldType() => clearField(4); + + @$pb.TagNumber(5) + $core.bool get frozen => $_getBF(4); + @$pb.TagNumber(5) + set frozen($core.bool v) { $_setBool(4, v); } + @$pb.TagNumber(5) + $core.bool hasFrozen() => $_has(4); + @$pb.TagNumber(5) + void clearFrozen() => clearField(5); + + @$pb.TagNumber(6) + $core.bool get visibility => $_getBF(5); + @$pb.TagNumber(6) + set visibility($core.bool v) { $_setBool(5, v); } + @$pb.TagNumber(6) + $core.bool hasVisibility() => $_has(5); + @$pb.TagNumber(6) + void clearVisibility() => clearField(6); + + @$pb.TagNumber(7) + $core.int get width => $_getIZ(6); + @$pb.TagNumber(7) + set width($core.int v) { $_setSignedInt32(6, v); } + @$pb.TagNumber(7) + $core.bool hasWidth() => $_has(6); + @$pb.TagNumber(7) + void clearWidth() => clearField(7); + + @$pb.TagNumber(8) + AnyData get typeOptions => $_getN(7); + @$pb.TagNumber(8) + set typeOptions(AnyData v) { setField(8, v); } + @$pb.TagNumber(8) + $core.bool hasTypeOptions() => $_has(7); + @$pb.TagNumber(8) + void clearTypeOptions() => clearField(8); + @$pb.TagNumber(8) + AnyData ensureTypeOptions() => $_ensure(7); +} + +class RepeatedField extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedField', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Field.create) + ..hasRequiredFields = false + ; + + RepeatedField._() : super(); + factory RepeatedField({ + $core.Iterable? items, + }) { + final _result = create(); + if (items != null) { + _result.items.addAll(items); + } + return _result; + } + factory RepeatedField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedField.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RepeatedField clone() => RepeatedField()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RepeatedField copyWith(void Function(RepeatedField) updates) => super.copyWith((message) => updates(message as RepeatedField)) as RepeatedField; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RepeatedField create() => RepeatedField._(); + RepeatedField createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RepeatedField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedField? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get items => $_getList(0); +} + +class AnyData extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AnyData', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeId') + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value', $pb.PbFieldType.OY) + ..hasRequiredFields = false + ; + + AnyData._() : super(); + factory AnyData({ + $core.String? typeId, + $core.List<$core.int>? value, + }) { + final _result = create(); + if (typeId != null) { + _result.typeId = typeId; + } + if (value != null) { + _result.value = value; + } + return _result; + } + factory AnyData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory AnyData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + AnyData clone() => AnyData()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + AnyData copyWith(void Function(AnyData) updates) => super.copyWith((message) => updates(message as AnyData)) as AnyData; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static AnyData create() => AnyData._(); + AnyData createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static AnyData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static AnyData? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get typeId => $_getSZ(0); + @$pb.TagNumber(1) + set typeId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasTypeId() => $_has(0); + @$pb.TagNumber(1) + void clearTypeId() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get value => $_getN(1); + @$pb.TagNumber(2) + set value($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasValue() => $_has(1); + @$pb.TagNumber(2) + void clearValue() => clearField(2); +} + +class RowMeta extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowMeta', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..m<$core.String, CellMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'RowMeta.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: CellMeta.create) + ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) + ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') + ..hasRequiredFields = false + ; + + RowMeta._() : super(); + factory RowMeta({ + $core.String? id, + $core.String? gridId, + $core.Map<$core.String, CellMeta>? cellByFieldId, + $core.int? height, + $core.bool? visibility, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (gridId != null) { + _result.gridId = gridId; + } + if (cellByFieldId != null) { + _result.cellByFieldId.addAll(cellByFieldId); + } + if (height != null) { + _result.height = height; + } + if (visibility != null) { + _result.visibility = visibility; + } + return _result; + } + factory RowMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RowMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RowMeta clone() => RowMeta()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RowMeta copyWith(void Function(RowMeta) updates) => super.copyWith((message) => updates(message as RowMeta)) as RowMeta; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RowMeta create() => RowMeta._(); + RowMeta createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RowMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RowMeta? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get gridId => $_getSZ(1); + @$pb.TagNumber(2) + set gridId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasGridId() => $_has(1); + @$pb.TagNumber(2) + void clearGridId() => clearField(2); + + @$pb.TagNumber(3) + $core.Map<$core.String, CellMeta> get cellByFieldId => $_getMap(2); + + @$pb.TagNumber(4) + $core.int get height => $_getIZ(3); + @$pb.TagNumber(4) + set height($core.int v) { $_setSignedInt32(3, v); } + @$pb.TagNumber(4) + $core.bool hasHeight() => $_has(3); + @$pb.TagNumber(4) + void clearHeight() => clearField(4); + + @$pb.TagNumber(5) + $core.bool get visibility => $_getBF(4); + @$pb.TagNumber(5) + set visibility($core.bool v) { $_setBool(4, v); } + @$pb.TagNumber(5) + $core.bool hasVisibility() => $_has(4); + @$pb.TagNumber(5) + void clearVisibility() => clearField(5); +} + +class CellMeta extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellMeta', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOM(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: AnyData.create) + ..a<$core.int>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) + ..hasRequiredFields = false + ; + + CellMeta._() : super(); + factory CellMeta({ + $core.String? id, + $core.String? rowId, + $core.String? fieldId, + AnyData? data, + $core.int? height, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (rowId != null) { + _result.rowId = rowId; + } + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (data != null) { + _result.data = data; + } + if (height != null) { + _result.height = height; + } + return _result; + } + factory CellMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CellMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CellMeta clone() => CellMeta()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CellMeta copyWith(void Function(CellMeta) updates) => super.copyWith((message) => updates(message as CellMeta)) as CellMeta; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CellMeta create() => CellMeta._(); + CellMeta createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CellMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CellMeta? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get rowId => $_getSZ(1); + @$pb.TagNumber(2) + set rowId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasRowId() => $_has(1); + @$pb.TagNumber(2) + void clearRowId() => clearField(2); + + @$pb.TagNumber(3) + $core.String get fieldId => $_getSZ(2); + @$pb.TagNumber(3) + set fieldId($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasFieldId() => $_has(2); + @$pb.TagNumber(3) + void clearFieldId() => clearField(3); + + @$pb.TagNumber(4) + AnyData get data => $_getN(3); + @$pb.TagNumber(4) + set data(AnyData v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasData() => $_has(3); + @$pb.TagNumber(4) + void clearData() => clearField(4); + @$pb.TagNumber(4) + AnyData ensureData() => $_ensure(3); + + @$pb.TagNumber(5) + $core.int get height => $_getIZ(4); + @$pb.TagNumber(5) + set height($core.int v) { $_setSignedInt32(4, v); } + @$pb.TagNumber(5) + $core.bool hasHeight() => $_has(4); + @$pb.TagNumber(5) + void clearHeight() => clearField(5); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbenum.dart new file mode 100644 index 0000000000..2bb3da475b --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbenum.dart @@ -0,0 +1,34 @@ +/// +// Generated code. Do not modify. +// source: meta.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +// ignore_for_file: UNDEFINED_SHOWN_NAME +import 'dart:core' as $core; +import 'package:protobuf/protobuf.dart' as $pb; + +class FieldType extends $pb.ProtobufEnum { + static const FieldType RichText = FieldType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RichText'); + static const FieldType Number = FieldType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Number'); + static const FieldType DateTime = FieldType._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DateTime'); + static const FieldType SingleSelect = FieldType._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SingleSelect'); + static const FieldType MultiSelect = FieldType._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MultiSelect'); + static const FieldType Checkbox = FieldType._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Checkbox'); + + static const $core.List values = [ + RichText, + Number, + DateTime, + SingleSelect, + MultiSelect, + Checkbox, + ]; + + static final $core.Map<$core.int, FieldType> _byValue = $pb.ProtobufEnum.initByValue(values); + static FieldType? valueOf($core.int value) => _byValue[value]; + + const FieldType._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart new file mode 100644 index 0000000000..eb41930ba4 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -0,0 +1,125 @@ +/// +// Generated code. Do not modify. +// source: meta.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use fieldTypeDescriptor instead') +const FieldType$json = const { + '1': 'FieldType', + '2': const [ + const {'1': 'RichText', '2': 0}, + const {'1': 'Number', '2': 1}, + const {'1': 'DateTime', '2': 2}, + const {'1': 'SingleSelect', '2': 3}, + const {'1': 'MultiSelect', '2': 4}, + const {'1': 'Checkbox', '2': 5}, + ], +}; + +/// Descriptor for `FieldType`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List fieldTypeDescriptor = $convert.base64Decode('CglGaWVsZFR5cGUSDAoIUmljaFRleHQQABIKCgZOdW1iZXIQARIMCghEYXRlVGltZRACEhAKDFNpbmdsZVNlbGVjdBADEg8KC011bHRpU2VsZWN0EAQSDAoIQ2hlY2tib3gQBQ=='); +@$core.Deprecated('Use gridMetaDescriptor instead') +const GridMeta$json = const { + '1': 'GridMeta', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.Field', '10': 'fields'}, + const {'1': 'rows', '3': 3, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, + ], +}; + +/// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIcCgRyb3dzGAMgAygLMgguUm93TWV0YVIEcm93cw=='); +@$core.Deprecated('Use gridBlockDescriptor instead') +const GridBlock$json = const { + '1': 'GridBlock', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, + ], +}; + +/// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSDgoCaWQYASABKAlSAmlkEhwKBHJvd3MYAiADKAsyCC5Sb3dNZXRhUgRyb3dz'); +@$core.Deprecated('Use fieldDescriptor instead') +const Field$json = const { + '1': 'Field', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, + const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'}, + const {'1': 'field_type', '3': 4, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'}, + const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'}, + const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'}, + const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'}, + const {'1': 'type_options', '3': 8, '4': 1, '5': 11, '6': '.AnyData', '10': 'typeOptions'}, + ], +}; + +/// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIrCgx0eXBlX29wdGlvbnMYCCABKAsyCC5BbnlEYXRhUgt0eXBlT3B0aW9ucw=='); +@$core.Deprecated('Use repeatedFieldDescriptor instead') +const RepeatedField$json = const { + '1': 'RepeatedField', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Field', '10': 'items'}, + ], +}; + +/// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z'); +@$core.Deprecated('Use anyDataDescriptor instead') +const AnyData$json = const { + '1': 'AnyData', + '2': const [ + const {'1': 'type_id', '3': 1, '4': 1, '5': 9, '10': 'typeId'}, + const {'1': 'value', '3': 2, '4': 1, '5': 12, '10': 'value'}, + ], +}; + +/// Descriptor for `AnyData`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List anyDataDescriptor = $convert.base64Decode('CgdBbnlEYXRhEhcKB3R5cGVfaWQYASABKAlSBnR5cGVJZBIUCgV2YWx1ZRgCIAEoDFIFdmFsdWU='); +@$core.Deprecated('Use rowMetaDescriptor instead') +const RowMeta$json = const { + '1': 'RowMeta', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'cell_by_field_id', '3': 3, '4': 3, '5': 11, '6': '.RowMeta.CellByFieldIdEntry', '10': 'cellByFieldId'}, + const {'1': 'height', '3': 4, '4': 1, '5': 5, '10': 'height'}, + const {'1': 'visibility', '3': 5, '4': 1, '5': 8, '10': 'visibility'}, + ], + '3': const [RowMeta_CellByFieldIdEntry$json], +}; + +@$core.Deprecated('Use rowMetaDescriptor instead') +const RowMeta_CellByFieldIdEntry$json = const { + '1': 'CellByFieldIdEntry', + '2': const [ + const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'}, + const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.CellMeta', '10': 'value'}, + ], + '7': const {'7': true}, +}; + +/// Descriptor for `RowMeta`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List rowMetaDescriptor = $convert.base64Decode('CgdSb3dNZXRhEg4KAmlkGAEgASgJUgJpZBIXCgdncmlkX2lkGAIgASgJUgZncmlkSWQSRAoQY2VsbF9ieV9maWVsZF9pZBgDIAMoCzIbLlJvd01ldGEuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgEIAEoBVIGaGVpZ2h0Eh4KCnZpc2liaWxpdHkYBSABKAhSCnZpc2liaWxpdHkaSwoSQ2VsbEJ5RmllbGRJZEVudHJ5EhAKA2tleRgBIAEoCVIDa2V5Eh8KBXZhbHVlGAIgASgLMgkuQ2VsbE1ldGFSBXZhbHVlOgI4AQ=='); +@$core.Deprecated('Use cellMetaDescriptor instead') +const CellMeta$json = const { + '1': 'CellMeta', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, + const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'data', '3': 4, '4': 1, '5': 11, '6': '.AnyData', '10': 'data'}, + const {'1': 'height', '3': 5, '4': 1, '5': 5, '10': 'height'}, + ], +}; + +/// Descriptor for `CellMeta`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List cellMetaDescriptor = $convert.base64Decode('CghDZWxsTWV0YRIOCgJpZBgBIAEoCVICaWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIZCghmaWVsZF9pZBgDIAEoCVIHZmllbGRJZBIcCgRkYXRhGAQgASgLMgguQW55RGF0YVIEZGF0YRIWCgZoZWlnaHQYBSABKAVSBmhlaWdodA=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbserver.dart new file mode 100644 index 0000000000..fdd12ef0bf --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: meta.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'meta.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart index 3f0100c8d6..2c253e0494 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart @@ -1,2 +1,3 @@ // Auto-generated, do not edit export './grid.pb.dart'; +export './meta.pb.dart'; 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 29a15a76b3..ac47fe4a51 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 @@ -14,12 +14,14 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent GetRows = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRows'); static const GridEvent GetFields = GridEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields'); static const GridEvent CreateRow = GridEvent._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); + static const GridEvent UpdateCell = GridEvent._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); static const $core.List values = [ GetGridData, GetRows, GetFields, CreateRow, + UpdateCell, ]; 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 0791be4e50..145521943a 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 @@ -16,8 +16,9 @@ const GridEvent$json = const { const {'1': 'GetRows', '2': 1}, const {'1': 'GetFields', '2': 2}, const {'1': 'CreateRow', '2': 3}, + const {'1': 'UpdateCell', '2': 4}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABILCgdHZXRSb3dzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAM='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABILCgdHZXRSb3dzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAMSDgoKVXBkYXRlQ2VsbBAE'); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 087d5c51cd..8c91bf1341 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -56,7 +56,7 @@ pub(crate) async fn update_cell_handler( manager: AppData>, ) -> Result<(), FlowyError> { let cell: Cell = data.into_inner(); - let editor = manager.get_grid_editor(id.as_ref())?; - let _ = editor.create_empty_row().await?; + // let editor = manager.get_grid_editor(id.as_ref())?; + // let _ = editor.create_empty_row().await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 95eea5b9cc..83c12b2b78 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -4,7 +4,7 @@ use dashmap::DashMap; use flowy_collaboration::entities::revision::RepeatedRevision; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{Field, RawRow}; +use flowy_grid_data_model::entities::{Field, RowMeta}; use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; use lib_sqlite::ConnectionPool; @@ -77,18 +77,6 @@ impl GridManager { } } - pub fn save_rows(&self, rows: Vec) -> FlowyResult<()> { - let kv_persistence = self.get_kv_persistence()?; - let _ = kv_persistence.batch_set(rows)?; - Ok(()) - } - - pub fn save_fields(&self, fields: Vec) -> FlowyResult<()> { - let kv_persistence = self.get_kv_persistence()?; - let _ = kv_persistence.batch_set(fields)?; - Ok(()) - } - async fn get_or_create_grid_editor(&self, grid_id: &str) -> FlowyResult> { match self.editor_map.get(grid_id) { None => { 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 6884312f38..028f37bab5 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 @@ -29,6 +29,7 @@ pub enum GridEvent { GetRows = 1, GetFields = 2, CreateRow = 3, + UpdateCell = 4, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -42,6 +43,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { 1 => ::std::option::Option::Some(GridEvent::GetRows), 2 => ::std::option::Option::Some(GridEvent::GetFields), 3 => ::std::option::Option::Some(GridEvent::CreateRow), + 4 => ::std::option::Option::Some(GridEvent::UpdateCell), _ => ::std::option::Option::None } } @@ -52,6 +54,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::GetRows, GridEvent::GetFields, GridEvent::CreateRow, + GridEvent::UpdateCell, ]; values } @@ -80,9 +83,9 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*G\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\ + \n\x0fevent_map.proto*W\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\ \x0b\n\x07GetRows\x10\x01\x12\r\n\tGetFields\x10\x02\x12\r\n\tCreateRow\ - \x10\x03b\x06proto3\ + \x10\x03\x12\x0e\n\nUpdateCell\x10\x04b\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 0f5de19e98..e06c2e56b3 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 @@ -5,4 +5,5 @@ enum GridEvent { GetRows = 1; GetFields = 2; CreateRow = 3; + UpdateCell = 4; } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs index 1bce574abb..bfc2fc1568 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs @@ -1,7 +1,7 @@ use crate::manager::GridManager; use flowy_collaboration::client_grid::make_grid_delta; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{Field, FieldOrder, FieldType, Grid, RawCell, RawRow, RowOrder}; +use flowy_grid_data_model::entities::{CellMeta, Field, FieldType, Grid, GridMeta, RowMeta, RowOrder}; use lib_infra::uuid; use std::sync::Arc; @@ -9,7 +9,7 @@ pub struct GridBuilder { grid_manager: Arc, grid_id: String, fields: Vec, - rows: Vec, + rows: Vec, } impl GridBuilder { @@ -29,39 +29,32 @@ impl GridBuilder { } pub fn add_empty_row(mut self) -> Self { - let row = RawRow::new(&uuid(), &self.grid_id, vec![]); + let row = RowMeta::new(&uuid(), &self.grid_id, vec![]); self.rows.push(row); self } - pub fn add_row(mut self, cells: Vec) -> Self { - let row = RawRow::new(&uuid(), &self.grid_id, cells); + pub fn add_row(mut self, cells: Vec) -> Self { + let row = RowMeta::new(&uuid(), &self.grid_id, cells); self.rows.push(row); self } pub fn build(self) -> FlowyResult { - let field_orders = self.fields.iter().map(FieldOrder::from).collect::>(); - - let row_orders = self.rows.iter().map(RowOrder::from).collect::>(); - - let grid = Grid { - id: self.grid_id, - field_orders: field_orders.into(), - row_orders: row_orders.into(), + let grid_meta = GridMeta { + grid_id: self.grid_id, + fields: self.fields, + rows: self.rows, }; // let _ = check_rows(&self.fields, &self.rows)?; - let _ = self.grid_manager.save_rows(self.rows)?; - let _ = self.grid_manager.save_fields(self.fields)?; - - let delta = make_grid_delta(&grid); + let delta = make_grid_delta(&grid_meta); Ok(delta.to_delta_str()) } } #[allow(dead_code)] -fn check_rows(fields: &[Field], rows: &[RawRow]) -> FlowyResult<()> { +fn check_rows(fields: &[Field], rows: &[RowMeta]) -> FlowyResult<()> { let field_ids = fields.iter().map(|field| &field.id).collect::>(); for row in rows { let cell_field_ids = row.cell_by_field_id.keys().into_iter().collect::>(); 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 096735c07d..9bc7b6da05 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -3,19 +3,17 @@ use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use crate::services::stringify::stringify_deserialize; use dashmap::DashMap; -use flowy_collaboration::client_grid::{GridChange, GridPad}; +use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Cell, Field, Grid, RawCell, RawRow, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, + Cell, CellMeta, Field, Grid, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, RowMeta, }; use flowy_sync::{RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; use lib_infra::uuid; use lib_ot::core::PlainTextAttributes; - -use dashmap::mapref::one::Ref; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; use std::sync::Arc; @@ -24,12 +22,12 @@ use tokio::sync::RwLock; pub struct ClientGridEditor { grid_id: String, user: Arc, - grid_pad: Arc>, + grid_meta_pad: Arc>, rev_manager: Arc, kv_persistence: Arc, field_map: DashMap, - cell_map: DashMap, + cell_map: DashMap, } impl ClientGridEditor { @@ -45,13 +43,13 @@ impl ClientGridEditor { let rev_manager = Arc::new(rev_manager); let field_map = load_all_fields(&grid_pad, &kv_persistence).await?; - let grid_pad = Arc::new(RwLock::new(grid_pad)); + let grid_meta_pad = Arc::new(RwLock::new(grid_pad)); let cell_map = DashMap::new(); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), user, - grid_pad, + grid_meta_pad, rev_manager, kv_persistence, field_map, @@ -60,16 +58,15 @@ impl ClientGridEditor { } pub async fn create_empty_row(&self) -> FlowyResult<()> { - let row = RawRow::new(&uuid(), &self.grid_id, vec![]); - self.cell_map.insert(row.id.clone(), row.clone()); + let row = RowMeta::new(&uuid(), &self.grid_id, vec![]); self.create_row(row).await?; Ok(()) } - async fn create_row(&self, row: RawRow) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.create_row(&row)?)).await?; - self.cell_map.insert(row.id.clone(), row.clone()); - let _ = self.kv_persistence.set(row)?; + async fn create_row(&self, row: RowMeta) -> FlowyResult<()> { + let _ = self.modify(|grid| Ok(grid.create_row(row)?)).await?; + // self.cell_map.insert(row.id.clone(), row.clone()); + // let _ = self.kv_persistence.set(row)?; Ok(()) } @@ -87,8 +84,7 @@ impl ClientGridEditor { // } pub async fn create_field(&mut self, field: Field) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.create_field(&field)?)).await?; - let _ = self.kv_persistence.set(field)?; + let _ = self.modify(|grid| Ok(grid.create_field(field)?)).await?; Ok(()) } @@ -104,9 +100,9 @@ impl ClientGridEditor { .into_iter() .map(|row_order| row_order.row_id) .collect::>(); - let raw_rows: Vec = self.kv_persistence.batch_get(ids)?; + let row_metas: Vec = self.kv_persistence.batch_get(ids)?; - let make_cell = |field_id: String, raw_cell: RawCell| { + let make_cell = |field_id: String, raw_cell: CellMeta| { let some_field = self.field_map.get(&field_id); if some_field.is_none() { tracing::error!("Can't find the field with {}", field_id); @@ -128,15 +124,15 @@ impl ClientGridEditor { } }; - let rows = raw_rows + let rows = row_metas .into_par_iter() - .map(|raw_row| { + .map(|row_meta| { let mut row = Row { - id: raw_row.id.clone(), + id: row_meta.id.clone(), cell_by_field_id: Default::default(), - height: raw_row.height, + height: row_meta.height, }; - row.cell_by_field_id = raw_row + row.cell_by_field_id = row_meta .cell_by_field_id .into_par_iter() .flat_map(|(field_id, raw_cell)| make_cell(field_id, raw_cell)) @@ -163,18 +159,18 @@ impl ClientGridEditor { } pub async fn grid_data(&self) -> Grid { - self.grid_pad.read().await.grid_data() + self.grid_meta_pad.read().await.grid_data() } pub async fn delta_str(&self) -> String { - self.grid_pad.read().await.delta_str() + self.grid_meta_pad.read().await.delta_str() } async fn modify(&self, f: F) -> FlowyResult<()> where - F: for<'a> FnOnce(&'a mut GridPad) -> FlowyResult>, + F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult>, { - let mut write_guard = self.grid_pad.write().await; + let mut write_guard = self.grid_meta_pad.write().await; match f(&mut *write_guard)? { None => {} Some(change) => { @@ -206,13 +202,13 @@ impl ClientGridEditor { } async fn load_all_fields( - grid_pad: &GridPad, + grid_pad: &GridMetaPad, kv_persistence: &Arc, ) -> FlowyResult> { let field_ids = grid_pad - .field_orders() + .fields() .iter() - .map(|field_order| field_order.field_id.clone()) + .map(|field| field.id.clone()) .collect::>(); let fields = kv_persistence.batch_get::(field_ids)?; @@ -225,10 +221,10 @@ async fn load_all_fields( struct GridPadBuilder(); impl RevisionObjectBuilder for GridPadBuilder { - type Output = GridPad; + type Output = GridMetaPad; fn build_object(object_id: &str, revisions: Vec) -> FlowyResult { - let pad = GridPad::from_revisions(object_id, revisions)?; + let pad = GridMetaPad::from_revisions(object_id, revisions)?; Ok(pad) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs b/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs index bc398f9cf3..6577c52ecd 100644 --- a/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs +++ b/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs @@ -6,8 +6,6 @@ use flowy_database::{ schema::{kv_table, kv_table::dsl}, }; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::GridIdentifiable; - use lib_sqlite::ConnectionPool; use std::sync::Arc; @@ -135,33 +133,11 @@ impl<'a> KVTransaction for SqliteTransaction<'a> { } } -impl + GridIdentifiable> std::convert::From for KeyValue { - fn from(value: T) -> Self { - let key = value.id().to_string(); - let bytes: Bytes = value.try_into().unwrap(); - let value = bytes.to_vec(); - KeyValue { key, value } - } -} - -// -// impl std::convert::TryInto for KeyValue { - -// type Error = FlowyError; -// -// fn try_into(self) -> Result { -// let bytes = Bytes::from(self.value); -// RawRow::try_from(bytes) -// .map_err(|e| FlowyError::internal().context(format!("Deserialize into raw row failed: {:?}", e))) -// } -// } -// -// impl std::convert::TryInto for KeyValue { -// type Error = FlowyError; -// -// fn try_into(self) -> Result { -// let bytes = Bytes::from(self.value); -// Field::try_from(bytes) -// .map_err(|e| FlowyError::internal().context(format!("Deserialize into field failed: {:?}", e))) +// impl + GridIdentifiable> std::convert::From for KeyValue { +// fn from(value: T) -> Self { +// let key = value.id().to_string(); +// let bytes: Bytes = value.try_into().unwrap(); +// let value = bytes.to_vec(); +// KeyValue { key, value } // } // } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 51be4dac63..32b3f968b3 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -1,7 +1,7 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{Field, FieldOrder, Grid, RawRow, RepeatedFieldOrder, RowOrder}; +use flowy_grid_data_model::entities::{Field, FieldOrder, Grid, GridMeta, RowMeta, RowOrder}; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use std::sync::Arc; @@ -9,70 +9,55 @@ use std::sync::Arc; pub type GridDelta = PlainTextDelta; pub type GridDeltaBuilder = PlainTextDeltaBuilder; -pub struct GridPad { - pub(crate) grid: Arc, +pub struct GridMetaPad { + pub(crate) grid_meta: Arc, pub(crate) delta: GridDelta, } -impl GridPad { +impl GridMetaPad { pub fn from_delta(delta: GridDelta) -> CollaborateResult { let s = delta.to_str()?; - let grid: Grid = serde_json::from_str(&s) + let grid: GridMeta = serde_json::from_str(&s) .map_err(|e| CollaborateError::internal().context(format!("Deserialize delta to grid failed: {}", e)))?; Ok(Self { - grid: Arc::new(grid), + grid_meta: Arc::new(grid), delta, }) } pub fn from_revisions(_grid_id: &str, revisions: Vec) -> CollaborateResult { - let folder_delta: GridDelta = make_delta_from_revisions::(revisions)?; - Self::from_delta(folder_delta) + let grid_delta: GridDelta = make_delta_from_revisions::(revisions)?; + Self::from_delta(grid_delta) } - pub fn create_row(&mut self, row: &RawRow) -> CollaborateResult> { + pub fn create_row(&mut self, row: RowMeta) -> CollaborateResult> { self.modify_grid(|grid| { - let row_order = RowOrder { - grid_id: grid.id.clone(), - row_id: row.id.clone(), - visibility: true, - }; - grid.row_orders.push(row_order); + grid.rows.push(row); Ok(Some(())) }) } - pub fn create_field(&mut self, field: &Field) -> CollaborateResult> { + pub fn create_field(&mut self, field: Field) -> CollaborateResult> { self.modify_grid(|grid| { - let field_order = FieldOrder { - field_id: field.id.clone(), - visibility: true, - }; - grid.field_orders.push(field_order); + grid.fields.push(field); Ok(Some(())) }) } pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { self.modify_grid(|grid| { - grid.row_orders.retain(|row_order| !row_ids.contains(&row_order.row_id)); + grid.rows.retain(|row| !row_ids.contains(&row.id)); Ok(Some(())) }) } pub fn delete_field(&mut self, field_id: &str) -> CollaborateResult> { - self.modify_grid(|grid| { - match grid - .field_orders - .iter() - .position(|field_order| field_order.field_id == field_id) - { - None => Ok(None), - Some(index) => { - grid.field_orders.remove(index); - Ok(Some(())) - } + self.modify_grid(|grid| match grid.fields.iter().position(|field| field.id == field_id) { + None => Ok(None), + Some(index) => { + grid.fields.remove(index); + Ok(Some(())) } }) } @@ -82,28 +67,45 @@ impl GridPad { } pub fn grid_data(&self) -> Grid { - let grid_ref: &Grid = &self.grid; - grid_ref.clone() + let field_orders = self + .grid_meta + .fields + .iter() + .map(FieldOrder::from) + .collect::>(); + + let row_orders = self + .grid_meta + .rows + .iter() + .map(RowOrder::from) + .collect::>(); + + Grid { + id: "".to_string(), + field_orders, + row_orders, + } } pub fn delta_str(&self) -> String { self.delta.to_delta_str() } - pub fn field_orders(&self) -> &RepeatedFieldOrder { - &self.grid.field_orders + pub fn fields(&self) -> &[Field] { + &self.grid_meta.fields } pub fn modify_grid(&mut self, f: F) -> CollaborateResult> where - F: FnOnce(&mut Grid) -> CollaborateResult>, + F: FnOnce(&mut GridMeta) -> CollaborateResult>, { - let cloned_grid = self.grid.clone(); - match f(Arc::make_mut(&mut self.grid))? { + let cloned_grid = self.grid_meta.clone(); + match f(Arc::make_mut(&mut self.grid_meta))? { None => Ok(None), Some(_) => { let old = json_from_grid(&cloned_grid)?; - let new = json_from_grid(&self.grid)?; + let new = json_from_grid(&self.grid_meta)?; match cal_diff::(old, new) { None => Ok(None), Some(delta) => { @@ -116,7 +118,7 @@ impl GridPad { } } -fn json_from_grid(grid: &Arc) -> CollaborateResult { +fn json_from_grid(grid: &Arc) -> CollaborateResult { let json = serde_json::to_string(grid) .map_err(|err| internal_error(format!("Serialize grid to json str failed. {:?}", err)))?; Ok(json) @@ -128,28 +130,28 @@ pub struct GridChange { pub md5: String, } -pub fn make_grid_delta(grid: &Grid) -> GridDelta { - let json = serde_json::to_string(&grid).unwrap(); +pub fn make_grid_delta(grid_meta: &GridMeta) -> GridDelta { + let json = serde_json::to_string(&grid_meta).unwrap(); PlainTextDeltaBuilder::new().insert(&json).build() } -pub fn make_grid_revisions(user_id: &str, grid: &Grid) -> RepeatedRevision { - let delta = make_grid_delta(grid); +pub fn make_grid_revisions(user_id: &str, grid_meta: &GridMeta) -> RepeatedRevision { + let delta = make_grid_delta(grid_meta); let bytes = delta.to_bytes(); - let revision = Revision::initial_revision(user_id, &grid.id, bytes); + let revision = Revision::initial_revision(user_id, &grid_meta.grid_id, bytes); revision.into() } -impl std::default::Default for GridPad { +impl std::default::Default for GridMetaPad { fn default() -> Self { - let grid = Grid { - id: uuid(), - field_orders: Default::default(), - row_orders: Default::default(), + let grid = GridMeta { + grid_id: uuid(), + fields: vec![], + rows: vec![], }; let delta = make_grid_delta(&grid); - GridPad { - grid: Arc::new(grid), + GridMetaPad { + grid_meta: Arc::new(grid), delta, } } 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 f8b616c22a..ad85fe636b 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,3 +1,4 @@ +use crate::entities::{Field, RowMeta}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -6,239 +7,63 @@ use strum_macros::{Display, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 36; pub const DEFAULT_FIELD_WIDTH: i32 = 150; -pub trait GridIdentifiable { - fn id(&self) -> &str; -} - -#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, ProtoBuf)] pub struct Grid { #[pb(index = 1)] pub id: String, #[pb(index = 2)] - #[serde(flatten)] - pub field_orders: RepeatedFieldOrder, + pub field_orders: Vec, #[pb(index = 3)] - #[serde(flatten)] - pub row_orders: RepeatedRowOrder, + pub row_orders: Vec, } -#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, ProtoBuf)] pub struct FieldOrder { #[pb(index = 1)] pub field_id: String, - - #[pb(index = 2)] - pub visibility: bool, } impl std::convert::From<&Field> for FieldOrder { fn from(field: &Field) -> Self { Self { field_id: field.id.clone(), - visibility: true, } } } -#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, ProtoBuf)] pub struct RepeatedFieldOrder { #[pb(index = 1)] - #[serde(rename(serialize = "field_orders", deserialize = "field_orders"))] pub items: Vec, } -impl std::convert::From> for RepeatedFieldOrder { - fn from(items: Vec) -> Self { - Self { items } - } -} - impl std::ops::Deref for RepeatedFieldOrder { type Target = Vec; - fn deref(&self) -> &Self::Target { &self.items } } -impl std::ops::DerefMut for RepeatedFieldOrder { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.items - } -} - -#[derive(Debug, Clone, Default, ProtoBuf)] -pub struct Field { - #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub name: String, - - #[pb(index = 3)] - pub desc: String, - - #[pb(index = 4)] - pub field_type: FieldType, - - #[pb(index = 5)] - pub frozen: bool, - - #[pb(index = 6)] - pub width: i32, - - #[pb(index = 7)] - pub type_options: AnyData, -} - -impl Field { - pub fn new(id: &str, name: &str, desc: &str, field_type: FieldType) -> Self { - Self { - id: id.to_owned(), - name: name.to_string(), - desc: desc.to_string(), - field_type, - frozen: false, - width: DEFAULT_FIELD_WIDTH, - type_options: Default::default(), - } - } -} - -impl GridIdentifiable for Field { - fn id(&self) -> &str { - &self.id - } -} - -#[derive(Debug, Default, ProtoBuf)] -pub struct RepeatedField { - #[pb(index = 1)] - pub items: Vec, -} -impl std::ops::Deref for RepeatedField { - type Target = Vec; - fn deref(&self) -> &Self::Target { - &self.items - } -} - -impl std::ops::DerefMut for RepeatedField { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.items - } -} - -impl std::convert::From> for RepeatedField { - fn from(items: Vec) -> Self { - Self { items } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)] -pub enum FieldType { - RichText = 0, - Number = 1, - DateTime = 2, - SingleSelect = 3, - MultiSelect = 4, - Checkbox = 5, -} - -impl std::default::Default for FieldType { - fn default() -> Self { - FieldType::RichText - } -} - -impl FieldType { - #[allow(dead_code)] - pub fn type_id(&self) -> String { - let ty = self.clone(); - format!("{}", ty as u8) - } - - pub fn from_type_id(type_id: &str) -> Result { - match type_id { - "0" => Ok(FieldType::RichText), - "1" => Ok(FieldType::Number), - "2" => Ok(FieldType::DateTime), - "3" => Ok(FieldType::SingleSelect), - "4" => Ok(FieldType::MultiSelect), - "5" => Ok(FieldType::Checkbox), - _ => Err(format!("Invalid type_id: {}", type_id)), - } - } -} - -#[derive(Debug, Clone, Default, ProtoBuf)] -pub struct AnyData { - #[pb(index = 1)] - pub type_id: String, - - #[pb(index = 2)] - pub value: Vec, -} - -impl AnyData { - pub fn from_str(field_type: &FieldType, s: &str) -> AnyData { - Self::from_bytes(field_type, s.as_bytes().to_vec()) - } - - pub fn from_bytes>(field_type: &FieldType, bytes: T) -> AnyData { - AnyData { - type_id: field_type.type_id(), - value: bytes.as_ref().to_vec(), - } - } -} - -impl ToString for AnyData { - fn to_string(&self) -> String { - match String::from_utf8(self.value.clone()) { - Ok(s) => s, - Err(_) => "".to_owned(), - } - } -} - -#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Default, Clone, ProtoBuf)] pub struct RowOrder { #[pb(index = 1)] - pub grid_id: String, - - #[pb(index = 2)] pub row_id: String, - - #[pb(index = 3)] - pub visibility: bool, } -impl std::convert::From<&RawRow> for RowOrder { - fn from(row: &RawRow) -> Self { - Self { - grid_id: row.grid_id.clone(), - row_id: row.id.clone(), - visibility: true, - } +impl std::convert::From<&RowMeta> for RowOrder { + fn from(row: &RowMeta) -> Self { + Self { row_id: row.id.clone() } } } -#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, ProtoBuf)] pub struct RepeatedRowOrder { #[pb(index = 1)] - #[serde(rename(serialize = "row_orders", deserialize = "row_orders"))] pub items: Vec, } -impl std::convert::From> for RepeatedRowOrder { - fn from(items: Vec) -> Self { - Self { items } - } -} - impl std::ops::Deref for RepeatedRowOrder { type Target = Vec; fn deref(&self) -> &Self::Target { @@ -253,57 +78,14 @@ impl std::ops::DerefMut for RepeatedRowOrder { } #[derive(Debug, Default, ProtoBuf)] -pub struct RawRow { +pub struct Row { #[pb(index = 1)] pub id: String, #[pb(index = 2)] - pub grid_id: String, + pub cell_by_field_id: HashMap, #[pb(index = 3)] - pub cell_by_field_id: HashMap, - - #[pb(index = 4)] - pub height: i32, -} - -impl RawRow { - pub fn new(id: &str, grid_id: &str, cells: Vec) -> Self { - let cell_by_field_id = cells - .into_iter() - .map(|cell| (cell.id.clone(), cell)) - .collect::>(); - - Self { - id: id.to_owned(), - grid_id: grid_id.to_owned(), - cell_by_field_id, - height: DEFAULT_ROW_HEIGHT, - } - } -} - -impl GridIdentifiable for RawRow { - fn id(&self) -> &str { - &self.id - } -} - -#[derive(Debug, Default, ProtoBuf)] -pub struct RawCell { - #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub row_id: String, - - #[pb(index = 3)] - pub field_id: String, - - #[pb(index = 4)] - pub data: AnyData, - - #[pb(index = 5)] pub height: i32, } @@ -331,19 +113,6 @@ impl std::convert::From> for RepeatedRow { Self { items } } } - -#[derive(Debug, Default, ProtoBuf)] -pub struct Row { - #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub cell_by_field_id: HashMap, - - #[pb(index = 3)] - pub height: i32, -} - #[derive(Debug, Default, ProtoBuf)] pub struct Cell { #[pb(index = 1)] @@ -356,21 +125,6 @@ pub struct Cell { pub content: String, } -#[derive(Debug, Default, ProtoBuf)] -pub struct CellChangeset { - #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub row_id: String, - - #[pb(index = 3)] - pub field_id: String, - - #[pb(index = 4)] - pub data: String, -} - #[derive(ProtoBuf, Default)] pub struct CreateGridPayload { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs new file mode 100644 index 0000000000..22abf8905d --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -0,0 +1,215 @@ +use crate::entities::Row; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use strum_macros::{Display, EnumIter, EnumString}; + +pub const DEFAULT_ROW_HEIGHT: i32 = 36; +pub const DEFAULT_FIELD_WIDTH: i32 = 150; + +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +pub struct GridMeta { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub fields: Vec, + + #[pb(index = 3)] + pub rows: Vec, +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +pub struct GridBlock { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub rows: Vec, +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +pub struct Field { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub name: String, + + #[pb(index = 3)] + pub desc: String, + + #[pb(index = 4)] + pub field_type: FieldType, + + #[pb(index = 5)] + pub frozen: bool, + + #[pb(index = 6)] + pub visibility: bool, + + #[pb(index = 7)] + pub width: i32, + + #[pb(index = 8)] + pub type_options: AnyData, +} + +impl Field { + pub fn new(id: &str, name: &str, desc: &str, field_type: FieldType) -> Self { + Self { + id: id.to_owned(), + name: name.to_string(), + desc: desc.to_string(), + field_type, + frozen: false, + visibility: true, + width: DEFAULT_FIELD_WIDTH, + type_options: Default::default(), + } + } +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct RepeatedField { + #[pb(index = 1)] + pub items: Vec, +} +impl std::ops::Deref for RepeatedField { + type Target = Vec; + fn deref(&self) -> &Self::Target { + &self.items + } +} + +impl std::ops::DerefMut for RepeatedField { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.items + } +} + +impl std::convert::From> for RepeatedField { + fn from(items: Vec) -> Self { + Self { items } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)] +pub enum FieldType { + RichText = 0, + Number = 1, + DateTime = 2, + SingleSelect = 3, + MultiSelect = 4, + Checkbox = 5, +} + +impl std::default::Default for FieldType { + fn default() -> Self { + FieldType::RichText + } +} + +impl FieldType { + #[allow(dead_code)] + pub fn type_id(&self) -> String { + let ty = self.clone(); + format!("{}", ty as u8) + } + + pub fn from_type_id(type_id: &str) -> Result { + match type_id { + "0" => Ok(FieldType::RichText), + "1" => Ok(FieldType::Number), + "2" => Ok(FieldType::DateTime), + "3" => Ok(FieldType::SingleSelect), + "4" => Ok(FieldType::MultiSelect), + "5" => Ok(FieldType::Checkbox), + _ => Err(format!("Invalid type_id: {}", type_id)), + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] +pub struct AnyData { + #[pb(index = 1)] + pub type_id: String, + + #[pb(index = 2)] + pub value: Vec, +} + +impl AnyData { + pub fn from_str(field_type: &FieldType, s: &str) -> AnyData { + Self::from_bytes(field_type, s.as_bytes().to_vec()) + } + + pub fn from_bytes>(field_type: &FieldType, bytes: T) -> AnyData { + AnyData { + type_id: field_type.type_id(), + value: bytes.as_ref().to_vec(), + } + } +} + +impl ToString for AnyData { + fn to_string(&self) -> String { + match String::from_utf8(self.value.clone()) { + Ok(s) => s, + Err(_) => "".to_owned(), + } + } +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +pub struct RowMeta { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub grid_id: String, + + #[pb(index = 3)] + pub cell_by_field_id: HashMap, + + #[pb(index = 4)] + pub height: i32, + + #[pb(index = 5)] + pub visibility: bool, +} + +impl RowMeta { + pub fn new(id: &str, grid_id: &str, cells: Vec) -> Self { + let cell_by_field_id = cells + .into_iter() + .map(|cell| (cell.id.clone(), cell)) + .collect::>(); + + Self { + id: id.to_owned(), + grid_id: grid_id.to_owned(), + cell_by_field_id, + height: DEFAULT_ROW_HEIGHT, + visibility: true, + } + } +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +pub struct CellMeta { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub row_id: String, + + #[pb(index = 3)] + pub field_id: String, + + #[pb(index = 4)] + pub data: AnyData, + + #[pb(index = 5)] + pub height: i32, +} diff --git a/shared-lib/flowy-grid-data-model/src/entities/mod.rs b/shared-lib/flowy-grid-data-model/src/entities/mod.rs index 9ba72a1272..350f8092d5 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/mod.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/mod.rs @@ -1,3 +1,5 @@ mod grid; +mod meta; pub use grid::*; +pub use meta::*; 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 b1a732e42e..c4f57568e9 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 @@ -27,8 +27,8 @@ pub struct Grid { // message fields pub id: ::std::string::String, - pub field_orders: ::protobuf::SingularPtrField, - pub row_orders: ::protobuf::SingularPtrField, + pub field_orders: ::protobuf::RepeatedField, + pub row_orders: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -71,70 +71,54 @@ impl Grid { ::std::mem::replace(&mut self.id, ::std::string::String::new()) } - // .RepeatedFieldOrder field_orders = 2; + // repeated .FieldOrder field_orders = 2; - pub fn get_field_orders(&self) -> &RepeatedFieldOrder { - self.field_orders.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_field_orders(&self) -> &[FieldOrder] { + &self.field_orders } pub fn clear_field_orders(&mut self) { self.field_orders.clear(); } - pub fn has_field_orders(&self) -> bool { - self.field_orders.is_some() - } - // Param is passed by value, moved - pub fn set_field_orders(&mut self, v: RepeatedFieldOrder) { - self.field_orders = ::protobuf::SingularPtrField::some(v); + pub fn set_field_orders(&mut self, v: ::protobuf::RepeatedField) { + self.field_orders = v; } // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_field_orders(&mut self) -> &mut RepeatedFieldOrder { - if self.field_orders.is_none() { - self.field_orders.set_default(); - } - self.field_orders.as_mut().unwrap() + pub fn mut_field_orders(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.field_orders } // Take field - pub fn take_field_orders(&mut self) -> RepeatedFieldOrder { - self.field_orders.take().unwrap_or_else(|| RepeatedFieldOrder::new()) + pub fn take_field_orders(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.field_orders, ::protobuf::RepeatedField::new()) } - // .RepeatedRowOrder row_orders = 3; + // repeated .RowOrder row_orders = 3; - pub fn get_row_orders(&self) -> &RepeatedRowOrder { - self.row_orders.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_row_orders(&self) -> &[RowOrder] { + &self.row_orders } pub fn clear_row_orders(&mut self) { self.row_orders.clear(); } - pub fn has_row_orders(&self) -> bool { - self.row_orders.is_some() - } - // Param is passed by value, moved - pub fn set_row_orders(&mut self, v: RepeatedRowOrder) { - self.row_orders = ::protobuf::SingularPtrField::some(v); + pub fn set_row_orders(&mut self, v: ::protobuf::RepeatedField) { + self.row_orders = v; } // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_row_orders(&mut self) -> &mut RepeatedRowOrder { - if self.row_orders.is_none() { - self.row_orders.set_default(); - } - self.row_orders.as_mut().unwrap() + pub fn mut_row_orders(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.row_orders } // Take field - pub fn take_row_orders(&mut self) -> RepeatedRowOrder { - self.row_orders.take().unwrap_or_else(|| RepeatedRowOrder::new()) + pub fn take_row_orders(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.row_orders, ::protobuf::RepeatedField::new()) } } @@ -161,10 +145,10 @@ impl ::protobuf::Message for Grid { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; }, 2 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.field_orders)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.field_orders)?; }, 3 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.row_orders)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.row_orders)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -181,14 +165,14 @@ impl ::protobuf::Message for Grid { if !self.id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.id); } - if let Some(ref v) = self.field_orders.as_ref() { - let len = v.compute_size(); + for value in &self.field_orders { + let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - if let Some(ref v) = self.row_orders.as_ref() { - let len = v.compute_size(); + }; + for value in &self.row_orders { + let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } + }; my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -198,16 +182,16 @@ impl ::protobuf::Message for Grid { if !self.id.is_empty() { os.write_string(1, &self.id)?; } - if let Some(ref v) = self.field_orders.as_ref() { + for v in &self.field_orders { os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; - } - if let Some(ref v) = self.row_orders.as_ref() { + }; + for v in &self.row_orders { os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; - } + }; os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -251,12 +235,12 @@ impl ::protobuf::Message for Grid { |m: &Grid| { &m.id }, |m: &mut Grid| { &mut m.id }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "field_orders", |m: &Grid| { &m.field_orders }, |m: &mut Grid| { &mut m.field_orders }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "row_orders", |m: &Grid| { &m.row_orders }, |m: &mut Grid| { &mut m.row_orders }, @@ -300,7 +284,6 @@ impl ::protobuf::reflect::ProtobufValue for Grid { pub struct FieldOrder { // message fields pub field_id: ::std::string::String, - pub visibility: bool, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -342,21 +325,6 @@ impl FieldOrder { pub fn take_field_id(&mut self) -> ::std::string::String { ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) } - - // bool visibility = 2; - - - pub fn get_visibility(&self) -> bool { - self.visibility - } - pub fn clear_visibility(&mut self) { - self.visibility = false; - } - - // Param is passed by value, moved - pub fn set_visibility(&mut self, v: bool) { - self.visibility = v; - } } impl ::protobuf::Message for FieldOrder { @@ -371,13 +339,6 @@ impl ::protobuf::Message for FieldOrder { 1 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.visibility = tmp; - }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -393,9 +354,6 @@ impl ::protobuf::Message for FieldOrder { if !self.field_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.field_id); } - if self.visibility != false { - my_size += 2; - } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -405,9 +363,6 @@ impl ::protobuf::Message for FieldOrder { if !self.field_id.is_empty() { os.write_string(1, &self.field_id)?; } - if self.visibility != false { - os.write_bool(2, self.visibility)?; - } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -451,11 +406,6 @@ impl ::protobuf::Message for FieldOrder { |m: &FieldOrder| { &m.field_id }, |m: &mut FieldOrder| { &mut m.field_id }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "visibility", - |m: &FieldOrder| { &m.visibility }, - |m: &mut FieldOrder| { &mut m.visibility }, - )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "FieldOrder", fields, @@ -473,7 +423,6 @@ impl ::protobuf::Message for FieldOrder { impl ::protobuf::Clear for FieldOrder { fn clear(&mut self) { self.field_id.clear(); - self.visibility = false; self.unknown_fields.clear(); } } @@ -656,780 +605,10 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedFieldOrder { } } -#[derive(PartialEq,Clone,Default)] -pub struct Field { - // message fields - pub id: ::std::string::String, - pub name: ::std::string::String, - pub desc: ::std::string::String, - pub field_type: FieldType, - pub frozen: bool, - pub width: i32, - pub type_options: ::protobuf::SingularPtrField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Field { - fn default() -> &'a Field { - ::default_instance() - } -} - -impl Field { - pub fn new() -> Field { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string name = 2; - - - pub fn get_name(&self) -> &str { - &self.name - } - pub fn clear_name(&mut self) { - self.name.clear(); - } - - // Param is passed by value, moved - pub fn set_name(&mut self, v: ::std::string::String) { - self.name = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_name(&mut self) -> &mut ::std::string::String { - &mut self.name - } - - // Take field - pub fn take_name(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.name, ::std::string::String::new()) - } - - // string desc = 3; - - - pub fn get_desc(&self) -> &str { - &self.desc - } - pub fn clear_desc(&mut self) { - self.desc.clear(); - } - - // Param is passed by value, moved - pub fn set_desc(&mut self, v: ::std::string::String) { - self.desc = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_desc(&mut self) -> &mut ::std::string::String { - &mut self.desc - } - - // Take field - pub fn take_desc(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.desc, ::std::string::String::new()) - } - - // .FieldType field_type = 4; - - - pub fn get_field_type(&self) -> FieldType { - self.field_type - } - pub fn clear_field_type(&mut self) { - self.field_type = FieldType::RichText; - } - - // Param is passed by value, moved - pub fn set_field_type(&mut self, v: FieldType) { - self.field_type = v; - } - - // bool frozen = 5; - - - pub fn get_frozen(&self) -> bool { - self.frozen - } - pub fn clear_frozen(&mut self) { - self.frozen = false; - } - - // Param is passed by value, moved - pub fn set_frozen(&mut self, v: bool) { - self.frozen = v; - } - - // int32 width = 6; - - - pub fn get_width(&self) -> i32 { - self.width - } - pub fn clear_width(&mut self) { - self.width = 0; - } - - // Param is passed by value, moved - pub fn set_width(&mut self, v: i32) { - self.width = v; - } - - // .AnyData type_options = 7; - - - pub fn get_type_options(&self) -> &AnyData { - self.type_options.as_ref().unwrap_or_else(|| ::default_instance()) - } - pub fn clear_type_options(&mut self) { - self.type_options.clear(); - } - - pub fn has_type_options(&self) -> bool { - self.type_options.is_some() - } - - // Param is passed by value, moved - pub fn set_type_options(&mut self, v: AnyData) { - self.type_options = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_type_options(&mut self) -> &mut AnyData { - if self.type_options.is_none() { - self.type_options.set_default(); - } - self.type_options.as_mut().unwrap() - } - - // Take field - pub fn take_type_options(&mut self) -> AnyData { - self.type_options.take().unwrap_or_else(|| AnyData::new()) - } -} - -impl ::protobuf::Message for Field { - fn is_initialized(&self) -> bool { - for v in &self.type_options { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.desc)?; - }, - 4 => { - ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.field_type, 4, &mut self.unknown_fields)? - }, - 5 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.frozen = tmp; - }, - 6 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.width = tmp; - }, - 7 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.type_options)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.name.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.name); - } - if !self.desc.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.desc); - } - if self.field_type != FieldType::RichText { - my_size += ::protobuf::rt::enum_size(4, self.field_type); - } - if self.frozen != false { - my_size += 2; - } - if self.width != 0 { - my_size += ::protobuf::rt::value_size(6, self.width, ::protobuf::wire_format::WireTypeVarint); - } - if let Some(ref v) = self.type_options.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.name.is_empty() { - os.write_string(2, &self.name)?; - } - if !self.desc.is_empty() { - os.write_string(3, &self.desc)?; - } - if self.field_type != FieldType::RichText { - os.write_enum(4, ::protobuf::ProtobufEnum::value(&self.field_type))?; - } - if self.frozen != false { - os.write_bool(5, self.frozen)?; - } - if self.width != 0 { - os.write_int32(6, self.width)?; - } - if let Some(ref v) = self.type_options.as_ref() { - os.write_tag(7, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Field { - Field::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &Field| { &m.id }, - |m: &mut Field| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "name", - |m: &Field| { &m.name }, - |m: &mut Field| { &mut m.name }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "desc", - |m: &Field| { &m.desc }, - |m: &mut Field| { &mut m.desc }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( - "field_type", - |m: &Field| { &m.field_type }, - |m: &mut Field| { &mut m.field_type }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "frozen", - |m: &Field| { &m.frozen }, - |m: &mut Field| { &mut m.frozen }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "width", - |m: &Field| { &m.width }, - |m: &mut Field| { &mut m.width }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "type_options", - |m: &Field| { &m.type_options }, - |m: &mut Field| { &mut m.type_options }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "Field", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static Field { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(Field::new) - } -} - -impl ::protobuf::Clear for Field { - fn clear(&mut self) { - self.id.clear(); - self.name.clear(); - self.desc.clear(); - self.field_type = FieldType::RichText; - self.frozen = false; - self.width = 0; - self.type_options.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Field { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Field { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct RepeatedField { - // message fields - pub items: ::protobuf::RepeatedField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RepeatedField { - fn default() -> &'a RepeatedField { - ::default_instance() - } -} - -impl RepeatedField { - pub fn new() -> RepeatedField { - ::std::default::Default::default() - } - - // repeated .Field items = 1; - - - pub fn get_items(&self) -> &[Field] { - &self.items - } - pub fn clear_items(&mut self) { - self.items.clear(); - } - - // Param is passed by value, moved - pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { - self.items = v; - } - - // Mutable pointer to the field. - pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.items - } - - // Take field - pub fn take_items(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for RepeatedField { - fn is_initialized(&self) -> bool { - for v in &self.items { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.items { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.items { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RepeatedField { - RepeatedField::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "items", - |m: &RepeatedField| { &m.items }, - |m: &mut RepeatedField| { &mut m.items }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RepeatedField", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RepeatedField { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RepeatedField::new) - } -} - -impl ::protobuf::Clear for RepeatedField { - fn clear(&mut self) { - self.items.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RepeatedField { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RepeatedField { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct AnyData { - // message fields - pub type_id: ::std::string::String, - pub value: ::std::vec::Vec, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a AnyData { - fn default() -> &'a AnyData { - ::default_instance() - } -} - -impl AnyData { - pub fn new() -> AnyData { - ::std::default::Default::default() - } - - // string type_id = 1; - - - pub fn get_type_id(&self) -> &str { - &self.type_id - } - pub fn clear_type_id(&mut self) { - self.type_id.clear(); - } - - // Param is passed by value, moved - pub fn set_type_id(&mut self, v: ::std::string::String) { - self.type_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_type_id(&mut self) -> &mut ::std::string::String { - &mut self.type_id - } - - // Take field - pub fn take_type_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.type_id, ::std::string::String::new()) - } - - // bytes value = 2; - - - pub fn get_value(&self) -> &[u8] { - &self.value - } - pub fn clear_value(&mut self) { - self.value.clear(); - } - - // Param is passed by value, moved - pub fn set_value(&mut self, v: ::std::vec::Vec) { - self.value = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_value(&mut self) -> &mut ::std::vec::Vec { - &mut self.value - } - - // Take field - pub fn take_value(&mut self) -> ::std::vec::Vec { - ::std::mem::replace(&mut self.value, ::std::vec::Vec::new()) - } -} - -impl ::protobuf::Message for AnyData { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.type_id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.value)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.type_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.type_id); - } - if !self.value.is_empty() { - my_size += ::protobuf::rt::bytes_size(2, &self.value); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.type_id.is_empty() { - os.write_string(1, &self.type_id)?; - } - if !self.value.is_empty() { - os.write_bytes(2, &self.value)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> AnyData { - AnyData::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "type_id", - |m: &AnyData| { &m.type_id }, - |m: &mut AnyData| { &mut m.type_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( - "value", - |m: &AnyData| { &m.value }, - |m: &mut AnyData| { &mut m.value }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "AnyData", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static AnyData { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(AnyData::new) - } -} - -impl ::protobuf::Clear for AnyData { - fn clear(&mut self) { - self.type_id.clear(); - self.value.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for AnyData { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for AnyData { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct RowOrder { // message fields - pub grid_id: ::std::string::String, pub row_id: ::std::string::String, - pub visibility: bool, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -1446,33 +625,7 @@ impl RowOrder { ::std::default::Default::default() } - // string grid_id = 1; - - - pub fn get_grid_id(&self) -> &str { - &self.grid_id - } - pub fn clear_grid_id(&mut self) { - self.grid_id.clear(); - } - - // Param is passed by value, moved - pub fn set_grid_id(&mut self, v: ::std::string::String) { - self.grid_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { - &mut self.grid_id - } - - // Take field - pub fn take_grid_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) - } - - // string row_id = 2; + // string row_id = 1; pub fn get_row_id(&self) -> &str { @@ -1497,21 +650,6 @@ impl RowOrder { pub fn take_row_id(&mut self) -> ::std::string::String { ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) } - - // bool visibility = 3; - - - pub fn get_visibility(&self) -> bool { - self.visibility - } - pub fn clear_visibility(&mut self) { - self.visibility = false; - } - - // Param is passed by value, moved - pub fn set_visibility(&mut self, v: bool) { - self.visibility = v; - } } impl ::protobuf::Message for RowOrder { @@ -1524,18 +662,8 @@ impl ::protobuf::Message for RowOrder { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; - }, - 2 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; }, - 3 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.visibility = tmp; - }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -1548,14 +676,8 @@ impl ::protobuf::Message for RowOrder { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if !self.grid_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.grid_id); - } if !self.row_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.row_id); - } - if self.visibility != false { - my_size += 2; + my_size += ::protobuf::rt::string_size(1, &self.row_id); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -1563,14 +685,8 @@ impl ::protobuf::Message for RowOrder { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.grid_id.is_empty() { - os.write_string(1, &self.grid_id)?; - } if !self.row_id.is_empty() { - os.write_string(2, &self.row_id)?; - } - if self.visibility != false { - os.write_bool(3, self.visibility)?; + os.write_string(1, &self.row_id)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -1610,21 +726,11 @@ impl ::protobuf::Message for RowOrder { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "grid_id", - |m: &RowOrder| { &m.grid_id }, - |m: &mut RowOrder| { &mut m.grid_id }, - )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "row_id", |m: &RowOrder| { &m.row_id }, |m: &mut RowOrder| { &mut m.row_id }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "visibility", - |m: &RowOrder| { &m.visibility }, - |m: &mut RowOrder| { &mut m.visibility }, - )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "RowOrder", fields, @@ -1641,9 +747,7 @@ impl ::protobuf::Message for RowOrder { impl ::protobuf::Clear for RowOrder { fn clear(&mut self) { - self.grid_id.clear(); self.row_id.clear(); - self.visibility = false; self.unknown_fields.clear(); } } @@ -1826,780 +930,6 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedRowOrder { } } -#[derive(PartialEq,Clone,Default)] -pub struct RawRow { - // message fields - pub id: ::std::string::String, - pub grid_id: ::std::string::String, - pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, RawCell>, - pub height: i32, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RawRow { - fn default() -> &'a RawRow { - ::default_instance() - } -} - -impl RawRow { - pub fn new() -> RawRow { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string grid_id = 2; - - - pub fn get_grid_id(&self) -> &str { - &self.grid_id - } - pub fn clear_grid_id(&mut self) { - self.grid_id.clear(); - } - - // Param is passed by value, moved - pub fn set_grid_id(&mut self, v: ::std::string::String) { - self.grid_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { - &mut self.grid_id - } - - // Take field - pub fn take_grid_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) - } - - // repeated .RawRow.CellByFieldIdEntry cell_by_field_id = 3; - - - pub fn get_cell_by_field_id(&self) -> &::std::collections::HashMap<::std::string::String, RawCell> { - &self.cell_by_field_id - } - pub fn clear_cell_by_field_id(&mut self) { - self.cell_by_field_id.clear(); - } - - // Param is passed by value, moved - pub fn set_cell_by_field_id(&mut self, v: ::std::collections::HashMap<::std::string::String, RawCell>) { - self.cell_by_field_id = v; - } - - // Mutable pointer to the field. - pub fn mut_cell_by_field_id(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, RawCell> { - &mut self.cell_by_field_id - } - - // Take field - pub fn take_cell_by_field_id(&mut self) -> ::std::collections::HashMap<::std::string::String, RawCell> { - ::std::mem::replace(&mut self.cell_by_field_id, ::std::collections::HashMap::new()) - } - - // int32 height = 4; - - - pub fn get_height(&self) -> i32 { - self.height - } - pub fn clear_height(&mut self) { - self.height = 0; - } - - // Param is passed by value, moved - pub fn set_height(&mut self, v: i32) { - self.height = v; - } -} - -impl ::protobuf::Message for RawRow { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; - }, - 3 => { - ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; - }, - 4 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.height = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.grid_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.grid_id); - } - my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id); - if self.height != 0 { - my_size += ::protobuf::rt::value_size(4, self.height, ::protobuf::wire_format::WireTypeVarint); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.grid_id.is_empty() { - os.write_string(2, &self.grid_id)?; - } - ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id, os)?; - if self.height != 0 { - os.write_int32(4, self.height)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RawRow { - RawRow::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &RawRow| { &m.id }, - |m: &mut RawRow| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "grid_id", - |m: &RawRow| { &m.grid_id }, - |m: &mut RawRow| { &mut m.grid_id }, - )); - fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( - "cell_by_field_id", - |m: &RawRow| { &m.cell_by_field_id }, - |m: &mut RawRow| { &mut m.cell_by_field_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "height", - |m: &RawRow| { &m.height }, - |m: &mut RawRow| { &mut m.height }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RawRow", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RawRow { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RawRow::new) - } -} - -impl ::protobuf::Clear for RawRow { - fn clear(&mut self) { - self.id.clear(); - self.grid_id.clear(); - self.cell_by_field_id.clear(); - self.height = 0; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RawRow { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RawRow { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct RawCell { - // message fields - pub id: ::std::string::String, - pub row_id: ::std::string::String, - pub field_id: ::std::string::String, - pub data: ::protobuf::SingularPtrField, - pub height: i32, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RawCell { - fn default() -> &'a RawCell { - ::default_instance() - } -} - -impl RawCell { - pub fn new() -> RawCell { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string row_id = 2; - - - pub fn get_row_id(&self) -> &str { - &self.row_id - } - pub fn clear_row_id(&mut self) { - self.row_id.clear(); - } - - // Param is passed by value, moved - pub fn set_row_id(&mut self, v: ::std::string::String) { - self.row_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_row_id(&mut self) -> &mut ::std::string::String { - &mut self.row_id - } - - // Take field - pub fn take_row_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) - } - - // string field_id = 3; - - - pub fn get_field_id(&self) -> &str { - &self.field_id - } - pub fn clear_field_id(&mut self) { - self.field_id.clear(); - } - - // Param is passed by value, moved - pub fn set_field_id(&mut self, v: ::std::string::String) { - self.field_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_field_id(&mut self) -> &mut ::std::string::String { - &mut self.field_id - } - - // Take field - pub fn take_field_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) - } - - // .AnyData data = 4; - - - pub fn get_data(&self) -> &AnyData { - self.data.as_ref().unwrap_or_else(|| ::default_instance()) - } - pub fn clear_data(&mut self) { - self.data.clear(); - } - - pub fn has_data(&self) -> bool { - self.data.is_some() - } - - // Param is passed by value, moved - pub fn set_data(&mut self, v: AnyData) { - self.data = ::protobuf::SingularPtrField::some(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 AnyData { - if self.data.is_none() { - self.data.set_default(); - } - self.data.as_mut().unwrap() - } - - // Take field - pub fn take_data(&mut self) -> AnyData { - self.data.take().unwrap_or_else(|| AnyData::new()) - } - - // int32 height = 5; - - - pub fn get_height(&self) -> i32 { - self.height - } - pub fn clear_height(&mut self) { - self.height = 0; - } - - // Param is passed by value, moved - pub fn set_height(&mut self, v: i32) { - self.height = v; - } -} - -impl ::protobuf::Message for RawCell { - fn is_initialized(&self) -> bool { - for v in &self.data { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; - }, - 4 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.data)?; - }, - 5 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.height = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.row_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.row_id); - } - if !self.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.field_id); - } - if let Some(ref v) = self.data.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - if self.height != 0 { - my_size += ::protobuf::rt::value_size(5, self.height, ::protobuf::wire_format::WireTypeVarint); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.row_id.is_empty() { - os.write_string(2, &self.row_id)?; - } - if !self.field_id.is_empty() { - os.write_string(3, &self.field_id)?; - } - if let Some(ref v) = self.data.as_ref() { - os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - if self.height != 0 { - os.write_int32(5, self.height)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RawCell { - RawCell::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &RawCell| { &m.id }, - |m: &mut RawCell| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_id", - |m: &RawCell| { &m.row_id }, - |m: &mut RawCell| { &mut m.row_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "field_id", - |m: &RawCell| { &m.field_id }, - |m: &mut RawCell| { &mut m.field_id }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "data", - |m: &RawCell| { &m.data }, - |m: &mut RawCell| { &mut m.data }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "height", - |m: &RawCell| { &m.height }, - |m: &mut RawCell| { &mut m.height }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RawCell", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RawCell { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RawCell::new) - } -} - -impl ::protobuf::Clear for RawCell { - fn clear(&mut self) { - self.id.clear(); - self.row_id.clear(); - self.field_id.clear(); - self.data.clear(); - self.height = 0; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RawCell { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RawCell { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct RepeatedRow { - // message fields - pub items: ::protobuf::RepeatedField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RepeatedRow { - fn default() -> &'a RepeatedRow { - ::default_instance() - } -} - -impl RepeatedRow { - pub fn new() -> RepeatedRow { - ::std::default::Default::default() - } - - // repeated .Row items = 1; - - - pub fn get_items(&self) -> &[Row] { - &self.items - } - pub fn clear_items(&mut self) { - self.items.clear(); - } - - // Param is passed by value, moved - pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { - self.items = v; - } - - // Mutable pointer to the field. - pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.items - } - - // Take field - pub fn take_items(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for RepeatedRow { - fn is_initialized(&self) -> bool { - for v in &self.items { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.items { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.items { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RepeatedRow { - RepeatedRow::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "items", - |m: &RepeatedRow| { &m.items }, - |m: &mut RepeatedRow| { &mut m.items }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RepeatedRow", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RepeatedRow { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RepeatedRow::new) - } -} - -impl ::protobuf::Clear for RepeatedRow { - fn clear(&mut self) { - self.items.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RepeatedRow { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RepeatedRow { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct Row { // message fields @@ -2831,6 +1161,172 @@ impl ::protobuf::reflect::ProtobufValue for Row { } } +#[derive(PartialEq,Clone,Default)] +pub struct RepeatedRow { + // message fields + pub items: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RepeatedRow { + fn default() -> &'a RepeatedRow { + ::default_instance() + } +} + +impl RepeatedRow { + pub fn new() -> RepeatedRow { + ::std::default::Default::default() + } + + // repeated .Row items = 1; + + + pub fn get_items(&self) -> &[Row] { + &self.items + } + pub fn clear_items(&mut self) { + self.items.clear(); + } + + // Param is passed by value, moved + pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { + self.items = v; + } + + // Mutable pointer to the field. + pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.items + } + + // Take field + pub fn take_items(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for RepeatedRow { + fn is_initialized(&self) -> bool { + for v in &self.items { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.items { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.items { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RepeatedRow { + RepeatedRow::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "items", + |m: &RepeatedRow| { &m.items }, + |m: &mut RepeatedRow| { &mut m.items }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedRow", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RepeatedRow { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedRow::new) + } +} + +impl ::protobuf::Clear for RepeatedRow { + fn clear(&mut self) { + self.items.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RepeatedRow { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RepeatedRow { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct Cell { // message fields @@ -3074,291 +1570,6 @@ impl ::protobuf::reflect::ProtobufValue for Cell { } } -#[derive(PartialEq,Clone,Default)] -pub struct CellChangeset { - // message fields - pub id: ::std::string::String, - pub row_id: ::std::string::String, - pub field_id: ::std::string::String, - pub data: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a CellChangeset { - fn default() -> &'a CellChangeset { - ::default_instance() - } -} - -impl CellChangeset { - pub fn new() -> CellChangeset { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string row_id = 2; - - - pub fn get_row_id(&self) -> &str { - &self.row_id - } - pub fn clear_row_id(&mut self) { - self.row_id.clear(); - } - - // Param is passed by value, moved - pub fn set_row_id(&mut self, v: ::std::string::String) { - self.row_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_row_id(&mut self) -> &mut ::std::string::String { - &mut self.row_id - } - - // Take field - pub fn take_row_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) - } - - // string field_id = 3; - - - pub fn get_field_id(&self) -> &str { - &self.field_id - } - pub fn clear_field_id(&mut self) { - self.field_id.clear(); - } - - // Param is passed by value, moved - pub fn set_field_id(&mut self, v: ::std::string::String) { - self.field_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_field_id(&mut self) -> &mut ::std::string::String { - &mut self.field_id - } - - // Take field - pub fn take_field_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) - } - - // string data = 4; - - - pub fn get_data(&self) -> &str { - &self.data - } - pub fn clear_data(&mut self) { - self.data.clear(); - } - - // Param is passed by value, moved - pub fn set_data(&mut self, v: ::std::string::String) { - 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 { - &mut self.data - } - - // Take field - pub fn take_data(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.data, ::std::string::String::new()) - } -} - -impl ::protobuf::Message for CellChangeset { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; - }, - 4 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.row_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.row_id); - } - if !self.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.field_id); - } - if !self.data.is_empty() { - my_size += ::protobuf::rt::string_size(4, &self.data); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.row_id.is_empty() { - os.write_string(2, &self.row_id)?; - } - if !self.field_id.is_empty() { - os.write_string(3, &self.field_id)?; - } - if !self.data.is_empty() { - os.write_string(4, &self.data)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> CellChangeset { - CellChangeset::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &CellChangeset| { &m.id }, - |m: &mut CellChangeset| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_id", - |m: &CellChangeset| { &m.row_id }, - |m: &mut CellChangeset| { &mut m.row_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "field_id", - |m: &CellChangeset| { &m.field_id }, - |m: &mut CellChangeset| { &mut m.field_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "data", - |m: &CellChangeset| { &m.data }, - |m: &mut CellChangeset| { &mut m.data }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "CellChangeset", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static CellChangeset { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(CellChangeset::new) - } -} - -impl ::protobuf::Clear for CellChangeset { - fn clear(&mut self) { - self.id.clear(); - self.row_id.clear(); - self.field_id.clear(); - self.data.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for CellChangeset { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for CellChangeset { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct CreateGridPayload { // message fields @@ -4109,118 +2320,30 @@ impl ::protobuf::reflect::ProtobufValue for QueryRowPayload { } } -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum FieldType { - RichText = 0, - Number = 1, - DateTime = 2, - SingleSelect = 3, - MultiSelect = 4, - Checkbox = 5, -} - -impl ::protobuf::ProtobufEnum for FieldType { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(FieldType::RichText), - 1 => ::std::option::Option::Some(FieldType::Number), - 2 => ::std::option::Option::Some(FieldType::DateTime), - 3 => ::std::option::Option::Some(FieldType::SingleSelect), - 4 => ::std::option::Option::Some(FieldType::MultiSelect), - 5 => ::std::option::Option::Some(FieldType::Checkbox), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [FieldType] = &[ - FieldType::RichText, - FieldType::Number, - FieldType::DateTime, - FieldType::SingleSelect, - FieldType::MultiSelect, - FieldType::Checkbox, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("FieldType", file_descriptor_proto()) - }) - } -} - -impl ::std::marker::Copy for FieldType { -} - -impl ::std::default::Default for FieldType { - fn default() -> Self { - FieldType::RichText - } -} - -impl ::protobuf::reflect::ProtobufValue for FieldType { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) - } -} - static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ngrid.proto\"\x80\x01\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ - \x02id\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrd\ - erR\x0bfieldOrders\x120\n\nrow_orders\x18\x03\x20\x01(\x0b2\x11.Repeated\ - RowOrderR\trowOrders\"G\n\nFieldOrder\x12\x19\n\x08field_id\x18\x01\x20\ - \x01(\tR\x07fieldId\x12\x1e\n\nvisibility\x18\x02\x20\x01(\x08R\nvisibil\ - ity\"7\n\x12RepeatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b\ - .FieldOrderR\x05items\"\xc5\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\ - \x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\ - \x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\ - \x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\ - \x06frozen\x12\x14\n\x05width\x18\x06\x20\x01(\x05R\x05width\x12+\n\x0ct\ - ype_options\x18\x07\x20\x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\rRepe\ - atedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"\ - 8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\ - \x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"Z\n\x08RowOrder\x12\x17\ - \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\ - \x20\x01(\tR\x05rowId\x12\x1e\n\nvisibility\x18\x03\x20\x01(\x08R\nvisib\ - ility\"3\n\x10RepeatedRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\ - \t.RowOrderR\x05items\"\xda\x01\n\x06RawRow\x12\x0e\n\x02id\x18\x01\x20\ - \x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\x12C\n\ - \x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1a.RawRow.CellByFieldIdEntry\ - R\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06height\x1a\ - J\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\ - \x12\x1e\n\x05value\x18\x02\x20\x01(\x0b2\x08.RawCellR\x05value:\x028\ - \x01\"\x81\x01\n\x07RawCell\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ - \x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\ - \x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\ - \x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06heigh\ - t\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\ - \x05items\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ - \x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdE\ - ntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\ - \x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03ke\ - y\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\ - \"K\n\x04Cell\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08fie\ - ld_id\x18\x02\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x03\x20\ - \x01(\tR\x07content\"e\n\rCellChangeset\x12\x0e\n\x02id\x18\x01\x20\x01(\ - \tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08\ - field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x12\n\x04data\x18\x04\x20\ - \x01(\tR\x04data\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\ - \x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\t\ - R\x05value\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\ - \x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.Repe\ - atedFieldOrderR\x0bfieldOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07gri\ - d_id\x18\x01\x20\x01(\tR\x06gridId\x120\n\nrow_orders\x18\x02\x20\x01(\ - \x0b2\x11.RepeatedRowOrderR\trowOrders*d\n\tFieldType\x12\x0c\n\x08RichT\ - ext\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\x08Checkbox\x10\x05b\x06proto3\ + \n\ngrid.proto\"p\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ + \x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrderR\x0bfieldOr\ + ders\x12(\n\nrow_orders\x18\x03\x20\x03(\x0b2\t.RowOrderR\trowOrders\"'\ + \n\nFieldOrder\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"7\n\ + \x12RepeatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOr\ + derR\x05items\"!\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\ + \x05rowId\"3\n\x10RepeatedRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\ + \x0b2\t.RowOrderR\x05items\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\ + \x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.\ + Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\ + \x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\ + \x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.Cel\ + lR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\ + \x03(\x0b2\x04.RowR\x05items\"K\n\x04Cell\x12\x0e\n\x02id\x18\x01\x20\ + \x01(\tR\x02id\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12\ + \x18\n\x07content\x18\x03\x20\x01(\tR\x07content\"'\n\x11CreateGridPaylo\ + ad\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\ + \x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"d\n\x11QueryFieldPayload\ + \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orde\ + rs\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\\\n\ + \x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ + \x120\n\nrow_orders\x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrderR\trowOrde\ + rsb\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/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs new file mode 100644 index 0000000000..deaa2a75c2 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -0,0 +1,2040 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `meta.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct GridMeta { + // message fields + pub grid_id: ::std::string::String, + pub fields: ::protobuf::RepeatedField, + pub rows: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridMeta { + fn default() -> &'a GridMeta { + ::default_instance() + } +} + +impl GridMeta { + pub fn new() -> GridMeta { + ::std::default::Default::default() + } + + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // repeated .Field fields = 2; + + + pub fn get_fields(&self) -> &[Field] { + &self.fields + } + pub fn clear_fields(&mut self) { + self.fields.clear(); + } + + // Param is passed by value, moved + pub fn set_fields(&mut self, v: ::protobuf::RepeatedField) { + self.fields = v; + } + + // Mutable pointer to the field. + pub fn mut_fields(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.fields + } + + // Take field + pub fn take_fields(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new()) + } + + // repeated .RowMeta rows = 3; + + + pub fn get_rows(&self) -> &[RowMeta] { + &self.rows + } + pub fn clear_rows(&mut self) { + self.rows.clear(); + } + + // Param is passed by value, moved + pub fn set_rows(&mut self, v: ::protobuf::RepeatedField) { + self.rows = v; + } + + // Mutable pointer to the field. + pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.rows + } + + // Take field + pub fn take_rows(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for GridMeta { + fn is_initialized(&self) -> bool { + for v in &self.fields { + if !v.is_initialized() { + return false; + } + }; + for v in &self.rows { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 2 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.fields)?; + }, + 3 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + for value in &self.fields { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + for value in &self.rows { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + for v in &self.fields { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + for v in &self.rows { + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> GridMeta { + GridMeta::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &GridMeta| { &m.grid_id }, + |m: &mut GridMeta| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "fields", + |m: &GridMeta| { &m.fields }, + |m: &mut GridMeta| { &mut m.fields }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "rows", + |m: &GridMeta| { &m.rows }, + |m: &mut GridMeta| { &mut m.rows }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridMeta", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridMeta { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridMeta::new) + } +} + +impl ::protobuf::Clear for GridMeta { + fn clear(&mut self) { + self.grid_id.clear(); + self.fields.clear(); + self.rows.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridMeta { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridMeta { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct GridBlock { + // message fields + pub id: ::std::string::String, + pub rows: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridBlock { + fn default() -> &'a GridBlock { + ::default_instance() + } +} + +impl GridBlock { + pub fn new() -> GridBlock { + ::std::default::Default::default() + } + + // string id = 1; + + + pub fn get_id(&self) -> &str { + &self.id + } + pub fn clear_id(&mut self) { + self.id.clear(); + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: ::std::string::String) { + self.id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id + } + + // Take field + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) + } + + // repeated .RowMeta rows = 2; + + + pub fn get_rows(&self) -> &[RowMeta] { + &self.rows + } + pub fn clear_rows(&mut self) { + self.rows.clear(); + } + + // Param is passed by value, moved + pub fn set_rows(&mut self, v: ::protobuf::RepeatedField) { + self.rows = v; + } + + // Mutable pointer to the field. + pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.rows + } + + // Take field + pub fn take_rows(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for GridBlock { + fn is_initialized(&self) -> bool { + for v in &self.rows { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + for value in &self.rows { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + for v in &self.rows { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> GridBlock { + GridBlock::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &GridBlock| { &m.id }, + |m: &mut GridBlock| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "rows", + |m: &GridBlock| { &m.rows }, + |m: &mut GridBlock| { &mut m.rows }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlock", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridBlock { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlock::new) + } +} + +impl ::protobuf::Clear for GridBlock { + fn clear(&mut self) { + self.id.clear(); + self.rows.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridBlock { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridBlock { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct Field { + // message fields + pub id: ::std::string::String, + pub name: ::std::string::String, + pub desc: ::std::string::String, + pub field_type: FieldType, + pub frozen: bool, + pub visibility: bool, + pub width: i32, + pub type_options: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Field { + fn default() -> &'a Field { + ::default_instance() + } +} + +impl Field { + pub fn new() -> Field { + ::std::default::Default::default() + } + + // string id = 1; + + + pub fn get_id(&self) -> &str { + &self.id + } + pub fn clear_id(&mut self) { + self.id.clear(); + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: ::std::string::String) { + self.id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id + } + + // Take field + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) + } + + // string name = 2; + + + pub fn get_name(&self) -> &str { + &self.name + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + &mut self.name + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.name, ::std::string::String::new()) + } + + // string desc = 3; + + + pub fn get_desc(&self) -> &str { + &self.desc + } + pub fn clear_desc(&mut self) { + self.desc.clear(); + } + + // Param is passed by value, moved + pub fn set_desc(&mut self, v: ::std::string::String) { + self.desc = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_desc(&mut self) -> &mut ::std::string::String { + &mut self.desc + } + + // Take field + pub fn take_desc(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.desc, ::std::string::String::new()) + } + + // .FieldType field_type = 4; + + + pub fn get_field_type(&self) -> FieldType { + self.field_type + } + pub fn clear_field_type(&mut self) { + self.field_type = FieldType::RichText; + } + + // Param is passed by value, moved + pub fn set_field_type(&mut self, v: FieldType) { + self.field_type = v; + } + + // bool frozen = 5; + + + pub fn get_frozen(&self) -> bool { + self.frozen + } + pub fn clear_frozen(&mut self) { + self.frozen = false; + } + + // Param is passed by value, moved + pub fn set_frozen(&mut self, v: bool) { + self.frozen = v; + } + + // bool visibility = 6; + + + pub fn get_visibility(&self) -> bool { + self.visibility + } + pub fn clear_visibility(&mut self) { + self.visibility = false; + } + + // Param is passed by value, moved + pub fn set_visibility(&mut self, v: bool) { + self.visibility = v; + } + + // int32 width = 7; + + + pub fn get_width(&self) -> i32 { + self.width + } + pub fn clear_width(&mut self) { + self.width = 0; + } + + // Param is passed by value, moved + pub fn set_width(&mut self, v: i32) { + self.width = v; + } + + // .AnyData type_options = 8; + + + pub fn get_type_options(&self) -> &AnyData { + self.type_options.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_type_options(&mut self) { + self.type_options.clear(); + } + + pub fn has_type_options(&self) -> bool { + self.type_options.is_some() + } + + // Param is passed by value, moved + pub fn set_type_options(&mut self, v: AnyData) { + self.type_options = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_type_options(&mut self) -> &mut AnyData { + if self.type_options.is_none() { + self.type_options.set_default(); + } + self.type_options.as_mut().unwrap() + } + + // Take field + pub fn take_type_options(&mut self) -> AnyData { + self.type_options.take().unwrap_or_else(|| AnyData::new()) + } +} + +impl ::protobuf::Message for Field { + fn is_initialized(&self) -> bool { + for v in &self.type_options { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.desc)?; + }, + 4 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.field_type, 4, &mut self.unknown_fields)? + }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.frozen = tmp; + }, + 6 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.visibility = tmp; + }, + 7 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.width = tmp; + }, + 8 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.type_options)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + if !self.name.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.name); + } + if !self.desc.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.desc); + } + if self.field_type != FieldType::RichText { + my_size += ::protobuf::rt::enum_size(4, self.field_type); + } + if self.frozen != false { + my_size += 2; + } + if self.visibility != false { + my_size += 2; + } + if self.width != 0 { + my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint); + } + if let Some(ref v) = self.type_options.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + if !self.name.is_empty() { + os.write_string(2, &self.name)?; + } + if !self.desc.is_empty() { + os.write_string(3, &self.desc)?; + } + if self.field_type != FieldType::RichText { + os.write_enum(4, ::protobuf::ProtobufEnum::value(&self.field_type))?; + } + if self.frozen != false { + os.write_bool(5, self.frozen)?; + } + if self.visibility != false { + os.write_bool(6, self.visibility)?; + } + if self.width != 0 { + os.write_int32(7, self.width)?; + } + if let Some(ref v) = self.type_options.as_ref() { + os.write_tag(8, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Field { + Field::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &Field| { &m.id }, + |m: &mut Field| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &Field| { &m.name }, + |m: &mut Field| { &mut m.name }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "desc", + |m: &Field| { &m.desc }, + |m: &mut Field| { &mut m.desc }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "field_type", + |m: &Field| { &m.field_type }, + |m: &mut Field| { &mut m.field_type }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "frozen", + |m: &Field| { &m.frozen }, + |m: &mut Field| { &mut m.frozen }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "visibility", + |m: &Field| { &m.visibility }, + |m: &mut Field| { &mut m.visibility }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "width", + |m: &Field| { &m.width }, + |m: &mut Field| { &mut m.width }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "type_options", + |m: &Field| { &m.type_options }, + |m: &mut Field| { &mut m.type_options }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Field", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Field { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Field::new) + } +} + +impl ::protobuf::Clear for Field { + fn clear(&mut self) { + self.id.clear(); + self.name.clear(); + self.desc.clear(); + self.field_type = FieldType::RichText; + self.frozen = false; + self.visibility = false; + self.width = 0; + self.type_options.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Field { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Field { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct RepeatedField { + // message fields + pub items: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RepeatedField { + fn default() -> &'a RepeatedField { + ::default_instance() + } +} + +impl RepeatedField { + pub fn new() -> RepeatedField { + ::std::default::Default::default() + } + + // repeated .Field items = 1; + + + pub fn get_items(&self) -> &[Field] { + &self.items + } + pub fn clear_items(&mut self) { + self.items.clear(); + } + + // Param is passed by value, moved + pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { + self.items = v; + } + + // Mutable pointer to the field. + pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.items + } + + // Take field + pub fn take_items(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for RepeatedField { + fn is_initialized(&self) -> bool { + for v in &self.items { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.items { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.items { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RepeatedField { + RepeatedField::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "items", + |m: &RepeatedField| { &m.items }, + |m: &mut RepeatedField| { &mut m.items }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedField", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RepeatedField { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedField::new) + } +} + +impl ::protobuf::Clear for RepeatedField { + fn clear(&mut self) { + self.items.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RepeatedField { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RepeatedField { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct AnyData { + // message fields + pub type_id: ::std::string::String, + pub value: ::std::vec::Vec, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a AnyData { + fn default() -> &'a AnyData { + ::default_instance() + } +} + +impl AnyData { + pub fn new() -> AnyData { + ::std::default::Default::default() + } + + // string type_id = 1; + + + pub fn get_type_id(&self) -> &str { + &self.type_id + } + pub fn clear_type_id(&mut self) { + self.type_id.clear(); + } + + // Param is passed by value, moved + pub fn set_type_id(&mut self, v: ::std::string::String) { + self.type_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_type_id(&mut self) -> &mut ::std::string::String { + &mut self.type_id + } + + // Take field + pub fn take_type_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.type_id, ::std::string::String::new()) + } + + // bytes value = 2; + + + pub fn get_value(&self) -> &[u8] { + &self.value + } + pub fn clear_value(&mut self) { + self.value.clear(); + } + + // Param is passed by value, moved + pub fn set_value(&mut self, v: ::std::vec::Vec) { + self.value = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_value(&mut self) -> &mut ::std::vec::Vec { + &mut self.value + } + + // Take field + pub fn take_value(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.value, ::std::vec::Vec::new()) + } +} + +impl ::protobuf::Message for AnyData { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.type_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.value)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.type_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.type_id); + } + if !self.value.is_empty() { + my_size += ::protobuf::rt::bytes_size(2, &self.value); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.type_id.is_empty() { + os.write_string(1, &self.type_id)?; + } + if !self.value.is_empty() { + os.write_bytes(2, &self.value)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> AnyData { + AnyData::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "type_id", + |m: &AnyData| { &m.type_id }, + |m: &mut AnyData| { &mut m.type_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "value", + |m: &AnyData| { &m.value }, + |m: &mut AnyData| { &mut m.value }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "AnyData", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static AnyData { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(AnyData::new) + } +} + +impl ::protobuf::Clear for AnyData { + fn clear(&mut self) { + self.type_id.clear(); + self.value.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for AnyData { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for AnyData { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct RowMeta { + // message fields + pub id: ::std::string::String, + pub grid_id: ::std::string::String, + pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, CellMeta>, + pub height: i32, + pub visibility: bool, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RowMeta { + fn default() -> &'a RowMeta { + ::default_instance() + } +} + +impl RowMeta { + pub fn new() -> RowMeta { + ::std::default::Default::default() + } + + // string id = 1; + + + pub fn get_id(&self) -> &str { + &self.id + } + pub fn clear_id(&mut self) { + self.id.clear(); + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: ::std::string::String) { + self.id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id + } + + // Take field + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) + } + + // string grid_id = 2; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // repeated .RowMeta.CellByFieldIdEntry cell_by_field_id = 3; + + + pub fn get_cell_by_field_id(&self) -> &::std::collections::HashMap<::std::string::String, CellMeta> { + &self.cell_by_field_id + } + pub fn clear_cell_by_field_id(&mut self) { + self.cell_by_field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_cell_by_field_id(&mut self, v: ::std::collections::HashMap<::std::string::String, CellMeta>) { + self.cell_by_field_id = v; + } + + // Mutable pointer to the field. + pub fn mut_cell_by_field_id(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, CellMeta> { + &mut self.cell_by_field_id + } + + // Take field + pub fn take_cell_by_field_id(&mut self) -> ::std::collections::HashMap<::std::string::String, CellMeta> { + ::std::mem::replace(&mut self.cell_by_field_id, ::std::collections::HashMap::new()) + } + + // int32 height = 4; + + + pub fn get_height(&self) -> i32 { + self.height + } + pub fn clear_height(&mut self) { + self.height = 0; + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: i32) { + self.height = v; + } + + // bool visibility = 5; + + + pub fn get_visibility(&self) -> bool { + self.visibility + } + pub fn clear_visibility(&mut self) { + self.visibility = false; + } + + // Param is passed by value, moved + pub fn set_visibility(&mut self, v: bool) { + self.visibility = v; + } +} + +impl ::protobuf::Message for RowMeta { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 3 => { + ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; + }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.height = tmp; + }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.visibility = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.grid_id); + } + my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id); + if self.height != 0 { + my_size += ::protobuf::rt::value_size(4, self.height, ::protobuf::wire_format::WireTypeVarint); + } + if self.visibility != false { + my_size += 2; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + if !self.grid_id.is_empty() { + os.write_string(2, &self.grid_id)?; + } + ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id, os)?; + if self.height != 0 { + os.write_int32(4, self.height)?; + } + if self.visibility != false { + os.write_bool(5, self.visibility)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RowMeta { + RowMeta::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &RowMeta| { &m.id }, + |m: &mut RowMeta| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &RowMeta| { &m.grid_id }, + |m: &mut RowMeta| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( + "cell_by_field_id", + |m: &RowMeta| { &m.cell_by_field_id }, + |m: &mut RowMeta| { &mut m.cell_by_field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "height", + |m: &RowMeta| { &m.height }, + |m: &mut RowMeta| { &mut m.height }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "visibility", + |m: &RowMeta| { &m.visibility }, + |m: &mut RowMeta| { &mut m.visibility }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RowMeta", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RowMeta { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RowMeta::new) + } +} + +impl ::protobuf::Clear for RowMeta { + fn clear(&mut self) { + self.id.clear(); + self.grid_id.clear(); + self.cell_by_field_id.clear(); + self.height = 0; + self.visibility = false; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RowMeta { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RowMeta { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct CellMeta { + // message fields + pub id: ::std::string::String, + pub row_id: ::std::string::String, + pub field_id: ::std::string::String, + pub data: ::protobuf::SingularPtrField, + pub height: i32, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CellMeta { + fn default() -> &'a CellMeta { + ::default_instance() + } +} + +impl CellMeta { + pub fn new() -> CellMeta { + ::std::default::Default::default() + } + + // string id = 1; + + + pub fn get_id(&self) -> &str { + &self.id + } + pub fn clear_id(&mut self) { + self.id.clear(); + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: ::std::string::String) { + self.id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id + } + + // Take field + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) + } + + // string row_id = 2; + + + pub fn get_row_id(&self) -> &str { + &self.row_id + } + pub fn clear_row_id(&mut self) { + self.row_id.clear(); + } + + // Param is passed by value, moved + pub fn set_row_id(&mut self, v: ::std::string::String) { + self.row_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_id(&mut self) -> &mut ::std::string::String { + &mut self.row_id + } + + // Take field + pub fn take_row_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) + } + + // string field_id = 3; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // .AnyData data = 4; + + + pub fn get_data(&self) -> &AnyData { + self.data.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_data(&mut self) { + self.data.clear(); + } + + pub fn has_data(&self) -> bool { + self.data.is_some() + } + + // Param is passed by value, moved + pub fn set_data(&mut self, v: AnyData) { + self.data = ::protobuf::SingularPtrField::some(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 AnyData { + if self.data.is_none() { + self.data.set_default(); + } + self.data.as_mut().unwrap() + } + + // Take field + pub fn take_data(&mut self) -> AnyData { + self.data.take().unwrap_or_else(|| AnyData::new()) + } + + // int32 height = 5; + + + pub fn get_height(&self) -> i32 { + self.height + } + pub fn clear_height(&mut self) { + self.height = 0; + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: i32) { + self.height = v; + } +} + +impl ::protobuf::Message for CellMeta { + fn is_initialized(&self) -> bool { + for v in &self.data { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 4 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.data)?; + }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.height = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + if !self.row_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.row_id); + } + if !self.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.field_id); + } + if let Some(ref v) = self.data.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if self.height != 0 { + my_size += ::protobuf::rt::value_size(5, self.height, ::protobuf::wire_format::WireTypeVarint); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + if !self.row_id.is_empty() { + os.write_string(2, &self.row_id)?; + } + if !self.field_id.is_empty() { + os.write_string(3, &self.field_id)?; + } + if let Some(ref v) = self.data.as_ref() { + os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if self.height != 0 { + os.write_int32(5, self.height)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> CellMeta { + CellMeta::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &CellMeta| { &m.id }, + |m: &mut CellMeta| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &CellMeta| { &m.row_id }, + |m: &mut CellMeta| { &mut m.row_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &CellMeta| { &m.field_id }, + |m: &mut CellMeta| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "data", + |m: &CellMeta| { &m.data }, + |m: &mut CellMeta| { &mut m.data }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "height", + |m: &CellMeta| { &m.height }, + |m: &mut CellMeta| { &mut m.height }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CellMeta", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CellMeta { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CellMeta::new) + } +} + +impl ::protobuf::Clear for CellMeta { + fn clear(&mut self) { + self.id.clear(); + self.row_id.clear(); + self.field_id.clear(); + self.data.clear(); + self.height = 0; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CellMeta { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CellMeta { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum FieldType { + RichText = 0, + Number = 1, + DateTime = 2, + SingleSelect = 3, + MultiSelect = 4, + Checkbox = 5, +} + +impl ::protobuf::ProtobufEnum for FieldType { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(FieldType::RichText), + 1 => ::std::option::Option::Some(FieldType::Number), + 2 => ::std::option::Option::Some(FieldType::DateTime), + 3 => ::std::option::Option::Some(FieldType::SingleSelect), + 4 => ::std::option::Option::Some(FieldType::MultiSelect), + 5 => ::std::option::Option::Some(FieldType::Checkbox), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [FieldType] = &[ + FieldType::RichText, + FieldType::Number, + FieldType::DateTime, + FieldType::SingleSelect, + FieldType::MultiSelect, + FieldType::Checkbox, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("FieldType", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for FieldType { +} + +impl ::std::default::Default for FieldType { + fn default() -> Self { + FieldType::RichText + } +} + +impl ::protobuf::reflect::ProtobufValue for FieldType { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\nmeta.proto\"a\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \x06gridId\x12\x1e\n\x06fields\x18\x02\x20\x03(\x0b2\x06.FieldR\x06field\ + s\x12\x1c\n\x04rows\x18\x03\x20\x03(\x0b2\x08.RowMetaR\x04rows\"9\n\tGri\ + dBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x1c\n\x04rows\x18\ + \x02\x20\x03(\x0b2\x08.RowMetaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\ + \x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\ + \x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_typ\ + e\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\ + \x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\ + \nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\x12+\n\ + \x0ctype_options\x18\x08\x20\x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\ + \rRepeatedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05i\ + tems\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\ + \x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xfd\x01\n\x07RowMet\ + a\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\ + \x20\x01(\tR\x06gridId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\ + \x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\ + \x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\ + \nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\ + \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\ + value:\x028\x01\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ + \tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08\ + field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\ + \x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05\ + R\x06height*d\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\x08Checkbox\x10\x05b\x06prot\ + o3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs index 7b56c6cee8..d011b76000 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs @@ -3,3 +3,6 @@ mod grid; pub use grid::*; + +mod meta; +pub use meta::*; 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 04e82bea78..b8577c6e3c 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 @@ -2,72 +2,34 @@ syntax = "proto3"; message Grid { string id = 1; - RepeatedFieldOrder field_orders = 2; - RepeatedRowOrder row_orders = 3; + repeated FieldOrder field_orders = 2; + repeated RowOrder row_orders = 3; } message FieldOrder { string field_id = 1; - bool visibility = 2; } message RepeatedFieldOrder { repeated FieldOrder items = 1; } -message Field { - string id = 1; - string name = 2; - string desc = 3; - FieldType field_type = 4; - bool frozen = 5; - int32 width = 6; - AnyData type_options = 7; -} -message RepeatedField { - repeated Field items = 1; -} -message AnyData { - string type_id = 1; - bytes value = 2; -} message RowOrder { - string grid_id = 1; - string row_id = 2; - bool visibility = 3; + string row_id = 1; } message RepeatedRowOrder { repeated RowOrder items = 1; } -message RawRow { - string id = 1; - string grid_id = 2; - map cell_by_field_id = 3; - int32 height = 4; -} -message RawCell { - string id = 1; - string row_id = 2; - string field_id = 3; - AnyData data = 4; - int32 height = 5; -} -message RepeatedRow { - repeated Row items = 1; -} message Row { string id = 1; map cell_by_field_id = 2; int32 height = 3; } +message RepeatedRow { + repeated Row items = 1; +} message Cell { string id = 1; string field_id = 2; string content = 3; } -message CellChangeset { - string id = 1; - string row_id = 2; - string field_id = 3; - string data = 4; -} message CreateGridPayload { string name = 1; } @@ -82,11 +44,3 @@ message QueryRowPayload { string grid_id = 1; RepeatedRowOrder row_orders = 2; } -enum FieldType { - RichText = 0; - Number = 1; - DateTime = 2; - SingleSelect = 3; - MultiSelect = 4; - Checkbox = 5; -} diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto new file mode 100644 index 0000000000..24149d1fa0 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -0,0 +1,50 @@ +syntax = "proto3"; + +message GridMeta { + string grid_id = 1; + repeated Field fields = 2; + repeated RowMeta rows = 3; +} +message GridBlock { + string id = 1; + repeated RowMeta rows = 2; +} +message Field { + string id = 1; + string name = 2; + string desc = 3; + FieldType field_type = 4; + bool frozen = 5; + bool visibility = 6; + int32 width = 7; + AnyData type_options = 8; +} +message RepeatedField { + repeated Field items = 1; +} +message AnyData { + string type_id = 1; + bytes value = 2; +} +message RowMeta { + string id = 1; + string grid_id = 2; + map cell_by_field_id = 3; + int32 height = 4; + bool visibility = 5; +} +message CellMeta { + string id = 1; + string row_id = 2; + string field_id = 3; + AnyData data = 4; + int32 height = 5; +} +enum FieldType { + RichText = 0; + Number = 1; + DateTime = 2; + SingleSelect = 3; + MultiSelect = 4; + Checkbox = 5; +} diff --git a/shared-lib/flowy-grid-data-model/tests/serde_test.rs b/shared-lib/flowy-grid-data-model/tests/serde_test.rs index 287ffffa6b..203651a9a0 100644 --- a/shared-lib/flowy-grid-data-model/tests/serde_test.rs +++ b/shared-lib/flowy-grid-data-model/tests/serde_test.rs @@ -3,54 +3,36 @@ use flowy_grid_data_model::entities::*; #[test] fn grid_serde_test() { let grid_id = "1".to_owned(); - let field_orders = RepeatedFieldOrder { - items: vec![create_field_order("1")], - }; - let row_orders = RepeatedRowOrder { - items: vec![create_row_order(&grid_id, "1")], + let fields = vec![create_field("1")]; + let grid = GridMeta { + grid_id, + fields, + rows: vec![], }; - let grid = Grid { - id: grid_id, - field_orders, - row_orders, - }; - - let json = serde_json::to_string(&grid).unwrap(); - let grid2: Grid = serde_json::from_str(&json).unwrap(); - assert_eq!(grid, grid2); + let grid_1_json = serde_json::to_string(&grid).unwrap(); + let _: Grid = serde_json::from_str(&grid_1_json).unwrap(); assert_eq!( - json, - r#"{"id":"1","field_orders":[{"field_id":"1","visibility":false}],"row_orders":[{"grid_id":"1","row_id":"1","visibility":false}]}"# + grid_1_json, + r#"{"id":"1","fields":[{"id":"1","name":"Text Field","desc":"","field_type":"RichText","frozen":false,"visibility":true,"width":150,"type_options":{"type_id":"","value":[]}}],"rows":[]}"# ) } #[test] fn grid_default_serde_test() { let grid_id = "1".to_owned(); - let grid = Grid { - id: grid_id, - field_orders: RepeatedFieldOrder::default(), - row_orders: RepeatedRowOrder::default(), + let grid = GridMeta { + grid_id, + fields: vec![], + rows: vec![], }; let json = serde_json::to_string(&grid).unwrap(); - assert_eq!(json, r#"{"id":"1","field_orders":[],"row_orders":[]}"#) + assert_eq!(json, r#"{"id":"1","fields":[],"row_orders":[]}"#) } -fn create_field_order(field_id: &str) -> FieldOrder { - FieldOrder { - field_id: field_id.to_owned(), - visibility: false, - } -} - -fn create_row_order(grid_id: &str, row_id: &str) -> RowOrder { - RowOrder { - grid_id: grid_id.to_string(), - row_id: row_id.to_string(), - visibility: false, - } +fn create_field(field_id: &str) -> Field { + Field::new(field_id, "Text Field", "", FieldType::RichText) } #[allow(dead_code)] From 7ac6a1dc89b9e767f261c5fbb774b0794b0b6809 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 10 Mar 2022 17:14:10 +0800 Subject: [PATCH 08/28] chore: rename struct --- .../lib/startup/home_deps_resolver.dart | 1 + .../grid/cell_bloc/checkbox_cell_bloc.dart | 1 + .../grid/cell_bloc/date_cell_bloc.dart | 1 + .../grid/cell_bloc/number_cell_bloc.dart | 1 + .../grid/cell_bloc/selection_cell_bloc.dart | 1 + .../grid/cell_bloc/text_cell_bloc.dart | 1 + .../application/grid/column_bloc.dart | 2 +- .../lib/workspace/application/grid/data.dart | 1 + .../application/grid/grid_service.dart | 1 + .../plugins/grid/src/grid_page.dart | 2 +- .../plugins/grid/src/layout/layout.dart | 2 +- .../src/widgets/content/cell_builder.dart | 1 + .../src/widgets/content/cell_container.dart | 1 - .../src/widgets/content/checkbox_cell.dart | 1 + .../grid/src/widgets/content/date_cell.dart | 1 + .../grid/src/widgets/content/number_cell.dart | 1 + .../src/widgets/content/selection_cell.dart | 1 + .../grid/src/widgets/content/text_cell.dart | 1 + .../grid/src/widgets/header/header.dart | 2 +- .../grid/src/widgets/header/header_cell.dart | 2 +- .../flowy_sdk/lib/dispatch/dispatch.dart | 1 - .../flowy-collaboration/protobuf.dart | 2 +- .../text_block_info.pb.dart | 412 ++++++++++++++++++ .../text_block_info.pbenum.dart | 7 + .../text_block_info.pbjson.dart | 78 ++++ .../text_block_info.pbserver.dart | 9 + .../flowy-grid-data-model/meta.pb.dart | 119 ++++- .../flowy-grid-data-model/meta.pbjson.dart | 26 +- .../src/{block_editor.rs => editor.rs} | 20 +- .../rust-lib/flowy-block/src/event_handler.rs | 22 +- .../rust-lib/flowy-block/src/event_map.rs | 4 +- frontend/rust-lib/flowy-block/src/lib.rs | 12 +- frontend/rust-lib/flowy-block/src/manager.rs | 89 ++-- frontend/rust-lib/flowy-block/src/queue.rs | 6 +- .../rust-lib/flowy-block/src/web_socket.rs | 20 +- .../flowy-block/tests/document/edit_script.rs | 6 +- .../2022-03-04-101530_flowy-grid/down.sql | 3 +- .../2022-03-04-101530_flowy-grid/up.sql | 9 + .../src/services/view/controller.rs | 4 +- .../flowy-folder/tests/workspace/helper.rs | 6 +- .../flowy-folder/tests/workspace/script.rs | 4 +- .../flowy-grid/src/services/grid_builder.rs | 2 +- .../flowy-net/src/http_server/document.rs | 20 +- .../flowy-net/src/local_server/persistence.rs | 6 +- .../flowy-net/src/local_server/server.rs | 10 +- .../flowy-sdk/src/deps_resolve/folder_deps.rs | 35 +- .../flowy-sdk/src/deps_resolve/mod.rs | 4 +- .../{block_deps.rs => text_block_deps.rs} | 20 +- frontend/rust-lib/flowy-sdk/src/lib.rs | 28 +- frontend/rust-lib/flowy-sdk/src/module.rs | 18 +- .../src/cache/disk/folder_rev_impl.rs | 0 .../src/cache/disk/grid_rev_impl.rs | 0 .../rust-lib/flowy-sync/src/cache/disk/mod.rs | 11 +- .../{sql_impl.rs => text_block_rev_impl.rs} | 6 +- frontend/rust-lib/flowy-sync/src/cache/mod.rs | 327 +------------- frontend/rust-lib/flowy-sync/src/lib.rs | 2 + .../flowy-sync/src/rev_persistence.rs | 322 ++++++++++++++ .../src/client_grid/block_pad.rs | 115 +++++ .../src/client_grid/grid_pad.rs | 20 +- .../src/client_grid/mod.rs | 2 + .../flowy-collaboration/src/entities/mod.rs | 2 +- .../{document_info.rs => text_block_info.rs} | 30 +- .../src/protobuf/model/mod.rs | 6 +- .../{document_info.rs => text_block_info.rs} | 244 +++++------ ...ument_info.proto => text_block_info.proto} | 10 +- .../src/server_document/document_manager.rs | 10 +- shared-lib/flowy-collaboration/src/util.rs | 14 +- .../src/entities/grid.rs | 4 +- .../src/entities/meta.rs | 17 +- .../src/protobuf/model/meta.rs | 385 ++++++++++++---- .../src/protobuf/proto/meta.proto | 9 +- .../flowy-grid-data-model/tests/serde_test.rs | 10 +- 72 files changed, 1788 insertions(+), 785 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbserver.dart rename frontend/rust-lib/flowy-block/src/{block_editor.rs => editor.rs} (95%) rename frontend/rust-lib/flowy-sdk/src/deps_resolve/{block_deps.rs => text_block_deps.rs} (85%) create mode 100644 frontend/rust-lib/flowy-sync/src/cache/disk/folder_rev_impl.rs create mode 100644 frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs rename frontend/rust-lib/flowy-sync/src/cache/disk/{sql_impl.rs => text_block_rev_impl.rs} (98%) create mode 100644 frontend/rust-lib/flowy-sync/src/rev_persistence.rs create mode 100644 shared-lib/flowy-collaboration/src/client_grid/block_pad.rs rename shared-lib/flowy-collaboration/src/entities/{document_info.rs => text_block_info.rs} (78%) rename shared-lib/flowy-collaboration/src/protobuf/model/{document_info.rs => text_block_info.rs} (85%) rename shared-lib/flowy-collaboration/src/protobuf/proto/{document_info.proto => text_block_info.proto} (76%) diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 5b91d8a545..367390efa0 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -13,6 +13,7 @@ import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:get_it/get_it.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index 8f0de7fb32..a4ef372a8b 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index c8b5e97f2d..f24a9ee769 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart index b216550a81..4959b67902 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index 5e7a6e8e22..615c56f01e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart index cce4ff9224..0aa6c8e1a9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart index 39badc922a..6313920223 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart @@ -1,4 +1,4 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart index c32f87f1a2..96f89c9eb0 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -1,5 +1,6 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:equatable/equatable.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; class GridInfo { List rows; diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index e519b0a90d..a3f7f68760 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -3,6 +3,7 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; class GridService { Future> openGrid({required String gridId}) async { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index 7435ea0e5f..46c14d9b8d 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -6,7 +6,7 @@ import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_scrollview.dart'; import 'package:flowy_infra_ui/widget/error_page.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter/material.dart'; import 'package:styled_widget/styled_widget.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart index 3f076fc89f..14f4a672cf 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart @@ -1,4 +1,4 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'sizes.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index 754678ef8e..0abfc26047 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'checkbox_cell.dart'; import 'date_cell.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart index 56cc4e174f..0bfcc10caa 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart @@ -1,6 +1,5 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra/theme.dart'; -import 'package:flowy_sdk/log.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart index d3d2b57735..ffa94d428e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart @@ -1,6 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart index e1661fdffa..f36bdb386c 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart @@ -1,6 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/date_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart index 86b9863019..143f741b15 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart @@ -1,6 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/number_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart index 047cff7475..6dc2a1922a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart @@ -1,6 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; class SingleSelectCell extends StatefulWidget { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart index 7661ddc22f..eef2f79195 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -1,6 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index 83d24535f4..6a2adc619e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -5,7 +5,7 @@ import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index aacdcd251e..6217c9c344 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -2,7 +2,7 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.d import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart index f26efb17e4..715b9b2f4f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart @@ -22,7 +22,6 @@ import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart'; import 'package:flowy_sdk/protobuf/dart-ffi/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-block/protobuf.dart'; -import 'package:flowy_sdk/protobuf/flowy-collaboration/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart'; // ignore: unused_import diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/protobuf.dart index 050f20adc0..78a7a563db 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/protobuf.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/protobuf.dart @@ -1,5 +1,5 @@ // Auto-generated, do not edit export './folder_info.pb.dart'; export './ws_data.pb.dart'; +export './text_block_info.pb.dart'; export './revision.pb.dart'; -export './document_info.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pb.dart new file mode 100644 index 0000000000..43d315d340 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pb.dart @@ -0,0 +1,412 @@ +/// +// Generated code. Do not modify. +// source: text_block_info.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:fixnum/fixnum.dart' as $fixnum; +import 'package:protobuf/protobuf.dart' as $pb; + +import 'revision.pb.dart' as $0; + +class CreateTextBlockParams extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateTextBlockParams', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOM<$0.RepeatedRevision>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revisions', subBuilder: $0.RepeatedRevision.create) + ..hasRequiredFields = false + ; + + CreateTextBlockParams._() : super(); + factory CreateTextBlockParams({ + $core.String? id, + $0.RepeatedRevision? revisions, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (revisions != null) { + _result.revisions = revisions; + } + return _result; + } + factory CreateTextBlockParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CreateTextBlockParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CreateTextBlockParams clone() => CreateTextBlockParams()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CreateTextBlockParams copyWith(void Function(CreateTextBlockParams) updates) => super.copyWith((message) => updates(message as CreateTextBlockParams)) as CreateTextBlockParams; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CreateTextBlockParams create() => CreateTextBlockParams._(); + CreateTextBlockParams createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CreateTextBlockParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CreateTextBlockParams? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $0.RepeatedRevision get revisions => $_getN(1); + @$pb.TagNumber(2) + set revisions($0.RepeatedRevision v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasRevisions() => $_has(1); + @$pb.TagNumber(2) + void clearRevisions() => clearField(2); + @$pb.TagNumber(2) + $0.RepeatedRevision ensureRevisions() => $_ensure(1); +} + +class TextBlockInfo extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TextBlockInfo', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'text') + ..aInt64(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revId') + ..aInt64(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'baseRevId') + ..hasRequiredFields = false + ; + + TextBlockInfo._() : super(); + factory TextBlockInfo({ + $core.String? blockId, + $core.String? text, + $fixnum.Int64? revId, + $fixnum.Int64? baseRevId, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + if (text != null) { + _result.text = text; + } + if (revId != null) { + _result.revId = revId; + } + if (baseRevId != null) { + _result.baseRevId = baseRevId; + } + return _result; + } + factory TextBlockInfo.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory TextBlockInfo.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + TextBlockInfo clone() => TextBlockInfo()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + TextBlockInfo copyWith(void Function(TextBlockInfo) updates) => super.copyWith((message) => updates(message as TextBlockInfo)) as TextBlockInfo; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static TextBlockInfo create() => TextBlockInfo._(); + TextBlockInfo createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static TextBlockInfo getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static TextBlockInfo? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get text => $_getSZ(1); + @$pb.TagNumber(2) + set text($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasText() => $_has(1); + @$pb.TagNumber(2) + void clearText() => clearField(2); + + @$pb.TagNumber(3) + $fixnum.Int64 get revId => $_getI64(2); + @$pb.TagNumber(3) + set revId($fixnum.Int64 v) { $_setInt64(2, v); } + @$pb.TagNumber(3) + $core.bool hasRevId() => $_has(2); + @$pb.TagNumber(3) + void clearRevId() => clearField(3); + + @$pb.TagNumber(4) + $fixnum.Int64 get baseRevId => $_getI64(3); + @$pb.TagNumber(4) + set baseRevId($fixnum.Int64 v) { $_setInt64(3, v); } + @$pb.TagNumber(4) + $core.bool hasBaseRevId() => $_has(3); + @$pb.TagNumber(4) + void clearBaseRevId() => clearField(4); +} + +class ResetTextBlockParams extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ResetTextBlockParams', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..aOM<$0.RepeatedRevision>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revisions', subBuilder: $0.RepeatedRevision.create) + ..hasRequiredFields = false + ; + + ResetTextBlockParams._() : super(); + factory ResetTextBlockParams({ + $core.String? blockId, + $0.RepeatedRevision? revisions, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + if (revisions != null) { + _result.revisions = revisions; + } + return _result; + } + factory ResetTextBlockParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ResetTextBlockParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + ResetTextBlockParams clone() => ResetTextBlockParams()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ResetTextBlockParams copyWith(void Function(ResetTextBlockParams) updates) => super.copyWith((message) => updates(message as ResetTextBlockParams)) as ResetTextBlockParams; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ResetTextBlockParams create() => ResetTextBlockParams._(); + ResetTextBlockParams createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static ResetTextBlockParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ResetTextBlockParams? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); + + @$pb.TagNumber(2) + $0.RepeatedRevision get revisions => $_getN(1); + @$pb.TagNumber(2) + set revisions($0.RepeatedRevision v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasRevisions() => $_has(1); + @$pb.TagNumber(2) + void clearRevisions() => clearField(2); + @$pb.TagNumber(2) + $0.RepeatedRevision ensureRevisions() => $_ensure(1); +} + +class TextBlockDelta extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TextBlockDelta', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deltaStr') + ..hasRequiredFields = false + ; + + TextBlockDelta._() : super(); + factory TextBlockDelta({ + $core.String? blockId, + $core.String? deltaStr, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + if (deltaStr != null) { + _result.deltaStr = deltaStr; + } + return _result; + } + factory TextBlockDelta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory TextBlockDelta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + TextBlockDelta clone() => TextBlockDelta()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + TextBlockDelta copyWith(void Function(TextBlockDelta) updates) => super.copyWith((message) => updates(message as TextBlockDelta)) as TextBlockDelta; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static TextBlockDelta create() => TextBlockDelta._(); + TextBlockDelta createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static TextBlockDelta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static TextBlockDelta? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get deltaStr => $_getSZ(1); + @$pb.TagNumber(2) + set deltaStr($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasDeltaStr() => $_has(1); + @$pb.TagNumber(2) + void clearDeltaStr() => clearField(2); +} + +class NewDocUser extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'NewDocUser', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'userId') + ..aInt64(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'docId') + ..hasRequiredFields = false + ; + + NewDocUser._() : super(); + factory NewDocUser({ + $core.String? userId, + $fixnum.Int64? revId, + $core.String? docId, + }) { + final _result = create(); + if (userId != null) { + _result.userId = userId; + } + if (revId != null) { + _result.revId = revId; + } + if (docId != null) { + _result.docId = docId; + } + return _result; + } + factory NewDocUser.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory NewDocUser.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + NewDocUser clone() => NewDocUser()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + NewDocUser copyWith(void Function(NewDocUser) updates) => super.copyWith((message) => updates(message as NewDocUser)) as NewDocUser; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static NewDocUser create() => NewDocUser._(); + NewDocUser createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static NewDocUser getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static NewDocUser? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get userId => $_getSZ(0); + @$pb.TagNumber(1) + set userId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasUserId() => $_has(0); + @$pb.TagNumber(1) + void clearUserId() => clearField(1); + + @$pb.TagNumber(2) + $fixnum.Int64 get revId => $_getI64(1); + @$pb.TagNumber(2) + set revId($fixnum.Int64 v) { $_setInt64(1, v); } + @$pb.TagNumber(2) + $core.bool hasRevId() => $_has(1); + @$pb.TagNumber(2) + void clearRevId() => clearField(2); + + @$pb.TagNumber(3) + $core.String get docId => $_getSZ(2); + @$pb.TagNumber(3) + set docId($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasDocId() => $_has(2); + @$pb.TagNumber(3) + void clearDocId() => clearField(3); +} + +class TextBlockId extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TextBlockId', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value') + ..hasRequiredFields = false + ; + + TextBlockId._() : super(); + factory TextBlockId({ + $core.String? value, + }) { + final _result = create(); + if (value != null) { + _result.value = value; + } + return _result; + } + factory TextBlockId.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory TextBlockId.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + TextBlockId clone() => TextBlockId()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + TextBlockId copyWith(void Function(TextBlockId) updates) => super.copyWith((message) => updates(message as TextBlockId)) as TextBlockId; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static TextBlockId create() => TextBlockId._(); + TextBlockId createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static TextBlockId getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static TextBlockId? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get value => $_getSZ(0); + @$pb.TagNumber(1) + set value($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasValue() => $_has(0); + @$pb.TagNumber(1) + void clearValue() => clearField(1); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbenum.dart new file mode 100644 index 0000000000..20728d1388 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbenum.dart @@ -0,0 +1,7 @@ +/// +// Generated code. Do not modify. +// source: text_block_info.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbjson.dart new file mode 100644 index 0000000000..794b4ca433 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbjson.dart @@ -0,0 +1,78 @@ +/// +// Generated code. Do not modify. +// source: text_block_info.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use createTextBlockParamsDescriptor instead') +const CreateTextBlockParams$json = const { + '1': 'CreateTextBlockParams', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'revisions', '3': 2, '4': 1, '5': 11, '6': '.RepeatedRevision', '10': 'revisions'}, + ], +}; + +/// Descriptor for `CreateTextBlockParams`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List createTextBlockParamsDescriptor = $convert.base64Decode('ChVDcmVhdGVUZXh0QmxvY2tQYXJhbXMSDgoCaWQYASABKAlSAmlkEi8KCXJldmlzaW9ucxgCIAEoCzIRLlJlcGVhdGVkUmV2aXNpb25SCXJldmlzaW9ucw=='); +@$core.Deprecated('Use textBlockInfoDescriptor instead') +const TextBlockInfo$json = const { + '1': 'TextBlockInfo', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'text', '3': 2, '4': 1, '5': 9, '10': 'text'}, + const {'1': 'rev_id', '3': 3, '4': 1, '5': 3, '10': 'revId'}, + const {'1': 'base_rev_id', '3': 4, '4': 1, '5': 3, '10': 'baseRevId'}, + ], +}; + +/// Descriptor for `TextBlockInfo`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List textBlockInfoDescriptor = $convert.base64Decode('Cg1UZXh0QmxvY2tJbmZvEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEhIKBHRleHQYAiABKAlSBHRleHQSFQoGcmV2X2lkGAMgASgDUgVyZXZJZBIeCgtiYXNlX3Jldl9pZBgEIAEoA1IJYmFzZVJldklk'); +@$core.Deprecated('Use resetTextBlockParamsDescriptor instead') +const ResetTextBlockParams$json = const { + '1': 'ResetTextBlockParams', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'revisions', '3': 2, '4': 1, '5': 11, '6': '.RepeatedRevision', '10': 'revisions'}, + ], +}; + +/// Descriptor for `ResetTextBlockParams`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List resetTextBlockParamsDescriptor = $convert.base64Decode('ChRSZXNldFRleHRCbG9ja1BhcmFtcxIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIvCglyZXZpc2lvbnMYAiABKAsyES5SZXBlYXRlZFJldmlzaW9uUglyZXZpc2lvbnM='); +@$core.Deprecated('Use textBlockDeltaDescriptor instead') +const TextBlockDelta$json = const { + '1': 'TextBlockDelta', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'delta_str', '3': 2, '4': 1, '5': 9, '10': 'deltaStr'}, + ], +}; + +/// Descriptor for `TextBlockDelta`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List textBlockDeltaDescriptor = $convert.base64Decode('Cg5UZXh0QmxvY2tEZWx0YRIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIbCglkZWx0YV9zdHIYAiABKAlSCGRlbHRhU3Ry'); +@$core.Deprecated('Use newDocUserDescriptor instead') +const NewDocUser$json = const { + '1': 'NewDocUser', + '2': const [ + const {'1': 'user_id', '3': 1, '4': 1, '5': 9, '10': 'userId'}, + const {'1': 'rev_id', '3': 2, '4': 1, '5': 3, '10': 'revId'}, + const {'1': 'doc_id', '3': 3, '4': 1, '5': 9, '10': 'docId'}, + ], +}; + +/// Descriptor for `NewDocUser`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List newDocUserDescriptor = $convert.base64Decode('CgpOZXdEb2NVc2VyEhcKB3VzZXJfaWQYASABKAlSBnVzZXJJZBIVCgZyZXZfaWQYAiABKANSBXJldklkEhUKBmRvY19pZBgDIAEoCVIFZG9jSWQ='); +@$core.Deprecated('Use textBlockIdDescriptor instead') +const TextBlockId$json = const { + '1': 'TextBlockId', + '2': const [ + const {'1': 'value', '3': 1, '4': 1, '5': 9, '10': 'value'}, + ], +}; + +/// Descriptor for `TextBlockId`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List textBlockIdDescriptor = $convert.base64Decode('CgtUZXh0QmxvY2tJZBIUCgV2YWx1ZRgBIAEoCVIFdmFsdWU='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbserver.dart new file mode 100644 index 0000000000..5c81f4cb56 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/text_block_info.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: text_block_info.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'text_block_info.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 11370c1fd2..4ac91c7ff1 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -17,7 +17,7 @@ class GridMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: Field.create) - ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: Block.create) ..hasRequiredFields = false ; @@ -25,7 +25,7 @@ class GridMeta extends $pb.GeneratedMessage { factory GridMeta({ $core.String? gridId, $core.Iterable? fields, - $core.Iterable? rows, + $core.Iterable? blocks, }) { final _result = create(); if (gridId != null) { @@ -34,8 +34,8 @@ class GridMeta extends $pb.GeneratedMessage { if (fields != null) { _result.fields.addAll(fields); } - if (rows != null) { - _result.rows.addAll(rows); + if (blocks != null) { + _result.blocks.addAll(blocks); } return _result; } @@ -73,50 +73,55 @@ class GridMeta extends $pb.GeneratedMessage { $core.List get fields => $_getList(1); @$pb.TagNumber(3) - $core.List get rows => $_getList(2); + $core.List get blocks => $_getList(2); } -class GridBlock extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) +class Block extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Block', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startRowIndex', $pb.PbFieldType.O3) + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowCount', $pb.PbFieldType.O3) ..hasRequiredFields = false ; - GridBlock._() : super(); - factory GridBlock({ + Block._() : super(); + factory Block({ $core.String? id, - $core.Iterable? rows, + $core.int? startRowIndex, + $core.int? rowCount, }) { final _result = create(); if (id != null) { _result.id = id; } - if (rows != null) { - _result.rows.addAll(rows); + if (startRowIndex != null) { + _result.startRowIndex = startRowIndex; + } + if (rowCount != null) { + _result.rowCount = rowCount; } return _result; } - factory GridBlock.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GridBlock.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory Block.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Block.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - GridBlock clone() => GridBlock()..mergeFromMessage(this); + Block clone() => Block()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - GridBlock copyWith(void Function(GridBlock) updates) => super.copyWith((message) => updates(message as GridBlock)) as GridBlock; // ignore: deprecated_member_use + Block copyWith(void Function(Block) updates) => super.copyWith((message) => updates(message as Block)) as Block; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static GridBlock create() => GridBlock._(); - GridBlock createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static Block create() => Block._(); + Block createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static GridBlock getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GridBlock? _defaultInstance; + static Block getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Block? _defaultInstance; @$pb.TagNumber(1) $core.String get id => $_getSZ(0); @@ -127,6 +132,76 @@ class GridBlock extends $pb.GeneratedMessage { @$pb.TagNumber(1) void clearId() => clearField(1); + @$pb.TagNumber(2) + $core.int get startRowIndex => $_getIZ(1); + @$pb.TagNumber(2) + set startRowIndex($core.int v) { $_setSignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasStartRowIndex() => $_has(1); + @$pb.TagNumber(2) + void clearStartRowIndex() => clearField(2); + + @$pb.TagNumber(3) + $core.int get rowCount => $_getIZ(2); + @$pb.TagNumber(3) + set rowCount($core.int v) { $_setSignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasRowCount() => $_has(2); + @$pb.TagNumber(3) + void clearRowCount() => clearField(3); +} + +class BlockMeta extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlockMeta', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) + ..hasRequiredFields = false + ; + + BlockMeta._() : super(); + factory BlockMeta({ + $core.String? blockId, + $core.Iterable? rows, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + if (rows != null) { + _result.rows.addAll(rows); + } + return _result; + } + factory BlockMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory BlockMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + BlockMeta clone() => BlockMeta()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + BlockMeta copyWith(void Function(BlockMeta) updates) => super.copyWith((message) => updates(message as BlockMeta)) as BlockMeta; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static BlockMeta create() => BlockMeta._(); + BlockMeta createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static BlockMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static BlockMeta? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); + @$pb.TagNumber(2) $core.List get rows => $_getList(1); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index eb41930ba4..d0d94fd269 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -29,23 +29,35 @@ const GridMeta$json = const { '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.Field', '10': 'fields'}, - const {'1': 'rows', '3': 3, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, + const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.Block', '10': 'blocks'}, ], }; /// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIcCgRyb3dzGAMgAygLMgguUm93TWV0YVIEcm93cw=='); -@$core.Deprecated('Use gridBlockDescriptor instead') -const GridBlock$json = const { - '1': 'GridBlock', +final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIeCgZibG9ja3MYAyADKAsyBi5CbG9ja1IGYmxvY2tz'); +@$core.Deprecated('Use blockDescriptor instead') +const Block$json = const { + '1': 'Block', '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'start_row_index', '3': 2, '4': 1, '5': 5, '10': 'startRowIndex'}, + const {'1': 'row_count', '3': 3, '4': 1, '5': 5, '10': 'rowCount'}, + ], +}; + +/// Descriptor for `Block`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List blockDescriptor = $convert.base64Decode('CgVCbG9jaxIOCgJpZBgBIAEoCVICaWQSJgoPc3RhcnRfcm93X2luZGV4GAIgASgFUg1zdGFydFJvd0luZGV4EhsKCXJvd19jb3VudBgDIAEoBVIIcm93Q291bnQ='); +@$core.Deprecated('Use blockMetaDescriptor instead') +const BlockMeta$json = const { + '1': 'BlockMeta', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, ], }; -/// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSDgoCaWQYASABKAlSAmlkEhwKBHJvd3MYAiADKAsyCC5Sb3dNZXRhUgRyb3dz'); +/// Descriptor for `BlockMeta`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List blockMetaDescriptor = $convert.base64Decode('CglCbG9ja01ldGESGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSHAoEcm93cxgCIAMoCzIILlJvd01ldGFSBHJvd3M='); @$core.Deprecated('Use fieldDescriptor instead') const Field$json = const { '1': 'Field', diff --git a/frontend/rust-lib/flowy-block/src/block_editor.rs b/frontend/rust-lib/flowy-block/src/editor.rs similarity index 95% rename from frontend/rust-lib/flowy-block/src/block_editor.rs rename to frontend/rust-lib/flowy-block/src/editor.rs index f8b0f87c6b..d7977c19db 100644 --- a/frontend/rust-lib/flowy-block/src/block_editor.rs +++ b/frontend/rust-lib/flowy-block/src/editor.rs @@ -3,12 +3,12 @@ use crate::web_socket::{make_block_ws_manager, EditorCommandSender}; use crate::{ errors::FlowyError, queue::{EditBlockQueue, EditorCommand}, - BlockUser, + TextBlockUser, }; use bytes::Bytes; use flowy_collaboration::entities::ws_data::ServerRevisionWSData; use flowy_collaboration::{ - entities::{document_info::BlockInfo, revision::Revision}, + entities::{revision::Revision, text_block_info::TextBlockInfo}, errors::CollaborateResult, util::make_delta_from_revisions, }; @@ -24,7 +24,7 @@ use lib_ws::WSConnectState; use std::sync::Arc; use tokio::sync::{mpsc, oneshot}; -pub struct ClientBlockEditor { +pub struct ClientTextBlockEditor { pub doc_id: String, #[allow(dead_code)] rev_manager: Arc, @@ -32,10 +32,10 @@ pub struct ClientBlockEditor { edit_cmd_tx: EditorCommandSender, } -impl ClientBlockEditor { +impl ClientTextBlockEditor { pub(crate) async fn new( doc_id: &str, - user: Arc, + user: Arc, mut rev_manager: RevisionManager, rev_web_socket: Arc, cloud_service: Arc, @@ -174,7 +174,7 @@ impl ClientBlockEditor { } } -impl std::ops::Drop for ClientBlockEditor { +impl std::ops::Drop for ClientTextBlockEditor { fn drop(&mut self) { tracing::trace!("{} ClientBlockEditor was dropped", self.doc_id) } @@ -182,7 +182,7 @@ impl std::ops::Drop for ClientBlockEditor { // The edit queue will exit after the EditorCommandSender was dropped. fn spawn_edit_queue( - user: Arc, + user: Arc, rev_manager: Arc, delta: RichTextDelta, ) -> EditorCommandSender { @@ -193,7 +193,7 @@ fn spawn_edit_queue( } #[cfg(feature = "flowy_unit_test")] -impl ClientBlockEditor { +impl ClientTextBlockEditor { pub async fn doc_json(&self) -> FlowyResult { let (ret, rx) = oneshot::channel::>(); let msg = EditorCommand::ReadDeltaStr { ret }; @@ -217,14 +217,14 @@ impl ClientBlockEditor { struct BlockInfoBuilder(); impl RevisionObjectBuilder for BlockInfoBuilder { - type Output = BlockInfo; + type Output = TextBlockInfo; fn build_object(object_id: &str, revisions: Vec) -> FlowyResult { let (base_rev_id, rev_id) = revisions.last().unwrap().pair_rev_id(); let mut delta = make_delta_from_revisions(revisions)?; correct_delta(&mut delta); - Result::::Ok(BlockInfo { + Result::::Ok(TextBlockInfo { block_id: object_id.to_owned(), text: delta.to_delta_str(), rev_id, diff --git a/frontend/rust-lib/flowy-block/src/event_handler.rs b/frontend/rust-lib/flowy-block/src/event_handler.rs index 39761d3d7c..1457fc2992 100644 --- a/frontend/rust-lib/flowy-block/src/event_handler.rs +++ b/frontend/rust-lib/flowy-block/src/event_handler.rs @@ -1,28 +1,28 @@ use crate::entities::{ExportData, ExportParams, ExportPayload}; -use crate::BlockManager; -use flowy_collaboration::entities::document_info::{BlockDelta, BlockId}; +use crate::TextBlockManager; +use flowy_collaboration::entities::text_block_info::{TextBlockDelta, TextBlockId}; use flowy_error::FlowyError; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::convert::TryInto; use std::sync::Arc; pub(crate) async fn get_block_data_handler( - data: Data, - manager: AppData>, -) -> DataResult { - let block_id: BlockId = data.into_inner(); + data: Data, + manager: AppData>, +) -> DataResult { + let block_id: TextBlockId = data.into_inner(); let editor = manager.open_block(&block_id).await?; let delta_str = editor.delta_str().await?; - data_result(BlockDelta { + data_result(TextBlockDelta { block_id: block_id.into(), delta_str, }) } pub(crate) async fn apply_delta_handler( - data: Data, - manager: AppData>, -) -> DataResult { + data: Data, + manager: AppData>, +) -> DataResult { let block_delta = manager.receive_local_delta(data.into_inner()).await?; data_result(block_delta) } @@ -30,7 +30,7 @@ pub(crate) async fn apply_delta_handler( #[tracing::instrument(skip(data, manager), err)] pub(crate) async fn export_handler( data: Data, - manager: AppData>, + manager: AppData>, ) -> DataResult { let params: ExportParams = data.into_inner().try_into()?; let editor = manager.open_block(¶ms.view_id).await?; diff --git a/frontend/rust-lib/flowy-block/src/event_map.rs b/frontend/rust-lib/flowy-block/src/event_map.rs index f0cfda219c..8342102bf5 100644 --- a/frontend/rust-lib/flowy-block/src/event_map.rs +++ b/frontend/rust-lib/flowy-block/src/event_map.rs @@ -1,11 +1,11 @@ use crate::event_handler::*; -use crate::BlockManager; +use crate::TextBlockManager; use flowy_derive::{Flowy_Event, ProtoBuf_Enum}; use lib_dispatch::prelude::Module; use std::sync::Arc; use strum_macros::Display; -pub fn create(block_manager: Arc) -> Module { +pub fn create(block_manager: Arc) -> Module { let mut module = Module::new().name(env!("CARGO_PKG_NAME")).data(block_manager); module = module diff --git a/frontend/rust-lib/flowy-block/src/lib.rs b/frontend/rust-lib/flowy-block/src/lib.rs index 8f15fd7e31..b75ed7e147 100644 --- a/frontend/rust-lib/flowy-block/src/lib.rs +++ b/frontend/rust-lib/flowy-block/src/lib.rs @@ -1,4 +1,4 @@ -pub mod block_editor; +pub mod editor; mod entities; mod event_handler; pub mod event_map; @@ -15,13 +15,15 @@ pub mod errors { pub const DOCUMENT_SYNC_INTERVAL_IN_MILLIS: u64 = 1000; use crate::errors::FlowyError; -use flowy_collaboration::entities::document_info::{BlockId, BlockInfo, CreateBlockParams, ResetBlockParams}; +use flowy_collaboration::entities::text_block_info::{ + CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo, +}; use lib_infra::future::FutureResult; pub trait BlockCloudService: Send + Sync { - fn create_block(&self, token: &str, params: CreateBlockParams) -> FutureResult<(), FlowyError>; + fn create_block(&self, token: &str, params: CreateTextBlockParams) -> FutureResult<(), FlowyError>; - fn read_block(&self, token: &str, params: BlockId) -> FutureResult, FlowyError>; + fn read_block(&self, token: &str, params: TextBlockId) -> FutureResult, FlowyError>; - fn update_block(&self, token: &str, params: ResetBlockParams) -> FutureResult<(), FlowyError>; + fn update_block(&self, token: &str, params: ResetTextBlockParams) -> FutureResult<(), FlowyError>; } diff --git a/frontend/rust-lib/flowy-block/src/manager.rs b/frontend/rust-lib/flowy-block/src/manager.rs index 17ea23c7bb..091ca31bec 100644 --- a/frontend/rust-lib/flowy-block/src/manager.rs +++ b/frontend/rust-lib/flowy-block/src/manager.rs @@ -1,9 +1,9 @@ -use crate::{block_editor::ClientBlockEditor, errors::FlowyError, BlockCloudService}; +use crate::{editor::ClientTextBlockEditor, errors::FlowyError, BlockCloudService}; use bytes::Bytes; use dashmap::DashMap; use flowy_collaboration::entities::{ - document_info::{BlockDelta, BlockId}, revision::{md5, RepeatedRevision, Revision}, + text_block_info::{TextBlockDelta, TextBlockId}, ws_data::ServerRevisionWSData, }; use flowy_database::ConnectionPool; @@ -12,43 +12,42 @@ use flowy_sync::{RevisionCloudService, RevisionManager, RevisionPersistence, Rev use lib_infra::future::FutureResult; use std::{convert::TryInto, sync::Arc}; -pub trait BlockUser: Send + Sync { +pub trait TextBlockUser: Send + Sync { fn user_dir(&self) -> Result; fn user_id(&self) -> Result; fn token(&self) -> Result; fn db_pool(&self) -> Result, FlowyError>; } -pub struct BlockManager { +pub struct TextBlockManager { cloud_service: Arc, rev_web_socket: Arc, - block_editors: Arc, - block_user: Arc, + editor_map: Arc, + user: Arc, } -impl BlockManager { +impl TextBlockManager { pub fn new( cloud_service: Arc, - block_user: Arc, + text_block_user: Arc, rev_web_socket: Arc, ) -> Self { - let block_editors = Arc::new(BlockEditors::new()); Self { cloud_service, rev_web_socket, - block_editors, - block_user, + editor_map: Arc::new(TextBlockEditorMap::new()), + user: text_block_user, } } pub fn init(&self) -> FlowyResult<()> { - listen_ws_state_changed(self.rev_web_socket.clone(), self.block_editors.clone()); + listen_ws_state_changed(self.rev_web_socket.clone(), self.editor_map.clone()); Ok(()) } #[tracing::instrument(level = "debug", skip(self, block_id), fields(block_id), err)] - pub async fn open_block>(&self, block_id: T) -> Result, FlowyError> { + 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 @@ -58,7 +57,7 @@ impl BlockManager { pub fn close_block>(&self, block_id: T) -> Result<(), FlowyError> { let block_id = block_id.as_ref(); tracing::Span::current().record("block_id", &block_id); - self.block_editors.remove(block_id); + self.editor_map.remove(block_id); Ok(()) } @@ -66,16 +65,16 @@ impl BlockManager { pub fn delete_block>(&self, doc_id: T) -> Result<(), FlowyError> { let doc_id = doc_id.as_ref(); tracing::Span::current().record("doc_id", &doc_id); - self.block_editors.remove(doc_id); + self.editor_map.remove(doc_id); Ok(()) } #[tracing::instrument(level = "debug", skip(self, delta), fields(doc_id = %delta.block_id), err)] - pub async fn receive_local_delta(&self, delta: BlockDelta) -> Result { + pub async fn receive_local_delta(&self, delta: TextBlockDelta) -> Result { let editor = self.get_block_editor(&delta.block_id).await?; let _ = editor.compose_local_delta(Bytes::from(delta.delta_str)).await?; let document_json = editor.delta_str().await?; - Ok(BlockDelta { + Ok(TextBlockDelta { block_id: delta.block_id.clone(), delta_str: document_json, }) @@ -83,7 +82,7 @@ impl BlockManager { pub async fn create_block>(&self, doc_id: T, revisions: RepeatedRevision) -> FlowyResult<()> { let doc_id = doc_id.as_ref().to_owned(); - let db_pool = self.block_user.db_pool()?; + let db_pool = self.user.db_pool()?; // Maybe we could save the block to disk without creating the RevisionManager let rev_manager = self.make_block_rev_manager(&doc_id, db_pool)?; let _ = rev_manager.reset_object(revisions).await?; @@ -93,9 +92,9 @@ impl BlockManager { pub async fn receive_ws_data(&self, data: Bytes) { let result: Result = data.try_into(); match result { - Ok(data) => match self.block_editors.get(&data.object_id) { + Ok(data) => match self.editor_map.get(&data.object_id) { None => tracing::error!("Can't find any source handler for {:?}-{:?}", data.object_id, data.ty), - Some(block_editor) => match block_editor.receive_ws_data(data).await { + Some(editor) => match editor.receive_ws_data(data).await { Ok(_) => {} Err(e) => tracing::error!("{}", e), }, @@ -107,11 +106,11 @@ impl BlockManager { } } -impl BlockManager { - async fn get_block_editor(&self, block_id: &str) -> FlowyResult> { - match self.block_editors.get(block_id) { +impl TextBlockManager { + async fn get_block_editor(&self, block_id: &str) -> FlowyResult> { + match self.editor_map.get(block_id) { None => { - let db_pool = self.block_user.db_pool()?; + let db_pool = self.user.db_pool()?; self.make_block_editor(block_id, db_pool).await } Some(editor) => Ok(editor), @@ -122,36 +121,36 @@ impl BlockManager { &self, block_id: &str, pool: Arc, - ) -> Result, FlowyError> { - let user = self.block_user.clone(); - let token = self.block_user.token()?; + ) -> Result, FlowyError> { + let user = self.user.clone(); + let token = self.user.token()?; let rev_manager = self.make_block_rev_manager(block_id, pool.clone())?; - let cloud_service = Arc::new(BlockRevisionCloudService { + let cloud_service = Arc::new(TextBlockRevisionCloudService { token, server: self.cloud_service.clone(), }); let doc_editor = - ClientBlockEditor::new(block_id, user, rev_manager, self.rev_web_socket.clone(), cloud_service).await?; - self.block_editors.insert(block_id, &doc_editor); + ClientTextBlockEditor::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) } fn make_block_rev_manager(&self, doc_id: &str, pool: Arc) -> Result { - let user_id = self.block_user.user_id()?; + let user_id = self.user.user_id()?; let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, doc_id, pool)); Ok(RevisionManager::new(&user_id, doc_id, rev_persistence)) } } -struct BlockRevisionCloudService { +struct TextBlockRevisionCloudService { token: String, server: Arc, } -impl RevisionCloudService for BlockRevisionCloudService { +impl RevisionCloudService for TextBlockRevisionCloudService { #[tracing::instrument(level = "trace", skip(self))] fn fetch_object(&self, user_id: &str, object_id: &str) -> FutureResult, FlowyError> { - let params: BlockId = object_id.to_string().into(); + let params: TextBlockId = object_id.to_string().into(); let server = self.server.clone(); let token = self.token.clone(); let user_id = user_id.to_string(); @@ -177,32 +176,24 @@ impl RevisionCloudService for BlockRevisionCloudService { } } -pub struct BlockEditors { - inner: DashMap>, +pub struct TextBlockEditorMap { + inner: DashMap>, } -impl BlockEditors { +impl TextBlockEditorMap { fn new() -> Self { 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 contains(&self, block_id: &str) -> bool { - self.inner.get(block_id).is_some() - } - - pub(crate) fn get(&self, block_id: &str) -> Option> { - if !self.contains(block_id) { - return None; - } - let opened_doc = self.inner.get(block_id).unwrap(); - Some(opened_doc.clone()) + pub(crate) fn get(&self, block_id: &str) -> Option> { + Some(self.inner.get(block_id)?.clone()) } pub(crate) fn remove(&self, block_id: &str) { @@ -214,7 +205,7 @@ impl BlockEditors { } #[tracing::instrument(level = "trace", skip(web_socket, handlers))] -fn listen_ws_state_changed(web_socket: Arc, handlers: Arc) { +fn listen_ws_state_changed(web_socket: Arc, handlers: Arc) { tokio::spawn(async move { let mut notify = web_socket.subscribe_state_changed().await; while let Ok(state) = notify.recv().await { diff --git a/frontend/rust-lib/flowy-block/src/queue.rs b/frontend/rust-lib/flowy-block/src/queue.rs index 96e4e50f17..aaaca7dbb4 100644 --- a/frontend/rust-lib/flowy-block/src/queue.rs +++ b/frontend/rust-lib/flowy-block/src/queue.rs @@ -1,5 +1,5 @@ use crate::web_socket::EditorCommandReceiver; -use crate::BlockUser; +use crate::TextBlockUser; use async_stream::stream; use flowy_collaboration::util::make_delta_from_revisions; use flowy_collaboration::{ @@ -21,14 +21,14 @@ use tokio::sync::{oneshot, RwLock}; // serial. pub(crate) struct EditBlockQueue { document: Arc>, - user: Arc, + user: Arc, rev_manager: Arc, receiver: Option, } impl EditBlockQueue { pub(crate) fn new( - user: Arc, + user: Arc, rev_manager: Arc, delta: RichTextDelta, receiver: EditorCommandReceiver, diff --git a/frontend/rust-lib/flowy-block/src/web_socket.rs b/frontend/rust-lib/flowy-block/src/web_socket.rs index 27ec604129..c6033286af 100644 --- a/frontend/rust-lib/flowy-block/src/web_socket.rs +++ b/frontend/rust-lib/flowy-block/src/web_socket.rs @@ -31,11 +31,11 @@ pub(crate) async fn make_block_ws_manager( rev_web_socket: Arc, ) -> Arc { let ws_data_provider = Arc::new(WSDataProvider::new(&doc_id, Arc::new(rev_manager.clone()))); - let resolver = Arc::new(BlockConflictResolver { edit_cmd_tx }); + let resolver = Arc::new(TextBlockConflictResolver { edit_cmd_tx }); let conflict_controller = RichTextConflictController::new(&user_id, resolver, Arc::new(ws_data_provider.clone()), rev_manager); - let ws_data_stream = Arc::new(BlockRevisionWSDataStream::new(conflict_controller)); - let ws_data_sink = Arc::new(BlockWSDataSink(ws_data_provider)); + let ws_data_stream = Arc::new(TextBlockRevisionWSDataStream::new(conflict_controller)); + let ws_data_sink = Arc::new(TextBlockWSDataSink(ws_data_provider)); let ping_duration = Duration::from_millis(DOCUMENT_SYNC_INTERVAL_IN_MILLIS); let ws_manager = Arc::new(RevisionWebSocketManager::new( "Block", @@ -62,11 +62,11 @@ fn listen_document_ws_state(_user_id: &str, _doc_id: &str, mut subscriber: broad }); } -pub(crate) struct BlockRevisionWSDataStream { +pub(crate) struct TextBlockRevisionWSDataStream { conflict_controller: Arc, } -impl BlockRevisionWSDataStream { +impl TextBlockRevisionWSDataStream { pub fn new(conflict_controller: RichTextConflictController) -> Self { Self { conflict_controller: Arc::new(conflict_controller), @@ -74,7 +74,7 @@ impl BlockRevisionWSDataStream { } } -impl RevisionWSDataStream for BlockRevisionWSDataStream { +impl RevisionWSDataStream for TextBlockRevisionWSDataStream { fn receive_push_revision(&self, bytes: Bytes) -> BoxResultFuture<(), FlowyError> { let resolver = self.conflict_controller.clone(); Box::pin(async move { resolver.receive_bytes(bytes).await }) @@ -96,19 +96,19 @@ impl RevisionWSDataStream for BlockRevisionWSDataStream { } } -pub(crate) struct BlockWSDataSink(pub(crate) Arc); -impl RevisionWebSocketSink for BlockWSDataSink { +pub(crate) struct TextBlockWSDataSink(pub(crate) Arc); +impl RevisionWebSocketSink for TextBlockWSDataSink { fn next(&self) -> FutureResult, FlowyError> { let sink_provider = self.0.clone(); FutureResult::new(async move { sink_provider.next().await }) } } -struct BlockConflictResolver { +struct TextBlockConflictResolver { edit_cmd_tx: EditorCommandSender, } -impl ConflictResolver for BlockConflictResolver { +impl ConflictResolver for TextBlockConflictResolver { fn compose_delta(&self, delta: RichTextDelta) -> BoxResultFuture { let tx = self.edit_cmd_tx.clone(); Box::pin(async move { diff --git a/frontend/rust-lib/flowy-block/tests/document/edit_script.rs b/frontend/rust-lib/flowy-block/tests/document/edit_script.rs index 0109302e96..a06eb24a44 100644 --- a/frontend/rust-lib/flowy-block/tests/document/edit_script.rs +++ b/frontend/rust-lib/flowy-block/tests/document/edit_script.rs @@ -1,4 +1,4 @@ -use flowy_block::block_editor::ClientBlockEditor; +use flowy_block::editor::ClientTextBlockEditor; use flowy_block::DOCUMENT_SYNC_INTERVAL_IN_MILLIS; use flowy_collaboration::entities::revision::RevisionState; use flowy_test::{helper::ViewTest, FlowySDKTest}; @@ -19,7 +19,7 @@ pub enum EditorScript { pub struct EditorTest { pub sdk: FlowySDKTest, - pub editor: Arc, + pub editor: Arc, } impl EditorTest { @@ -27,7 +27,7 @@ impl EditorTest { let sdk = FlowySDKTest::default(); let _ = sdk.init_user().await; let test = ViewTest::new(&sdk).await; - let editor = sdk.block_manager.open_block(&test.view.id).await.unwrap(); + let editor = sdk.text_block_manager.open_block(&test.view.id).await.unwrap(); Self { sdk, editor } } diff --git a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql index 96473ec177..1447085d7f 100644 --- a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql +++ b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql @@ -1,2 +1,3 @@ -- This file should undo anything in `up.sql` -DROP TABLE kv_table; \ No newline at end of file +DROP TABLE kv_table; +DROP TABLE grid_rev_table; \ No newline at end of file diff --git a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql index edde5d7dfa..c8b592109b 100644 --- a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql +++ b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql @@ -2,4 +2,13 @@ CREATE TABLE kv_table ( key TEXT NOT NULL PRIMARY KEY, value BLOB NOT NULL DEFAULT (x'') +); + +CREATE TABLE grid_rev_table ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + object_id TEXT NOT NULL DEFAULT '', + base_rev_id BIGINT NOT NULL DEFAULT 0, + rev_id BIGINT NOT NULL DEFAULT 0, + data BLOB NOT NULL DEFAULT (x''), + state INTEGER NOT NULL DEFAULT 0 ); \ No newline at end of file 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 f09fad218d..4722aaad5d 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -14,8 +14,8 @@ use crate::{ }; use bytes::Bytes; use flowy_collaboration::entities::{ - document_info::BlockId, revision::{RepeatedRevision, Revision}, + text_block_info::TextBlockId, }; use flowy_database::kv::KV; use flowy_folder_data_model::entities::view::ViewDataType; @@ -147,7 +147,7 @@ impl ViewController { } #[tracing::instrument(level = "debug", skip(self,params), fields(doc_id = %params.value), err)] - pub(crate) async fn delete_view(&self, params: BlockId) -> Result<(), FlowyError> { + pub(crate) async fn delete_view(&self, params: TextBlockId) -> Result<(), FlowyError> { if let Some(view_id) = KV::get_str(LATEST_VIEW_ID) { if view_id == params.value { let _ = KV::remove(LATEST_VIEW_ID); diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs b/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs index f0e1107535..393c0f5699 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs @@ -1,4 +1,4 @@ -use flowy_collaboration::entities::document_info::BlockInfo; +use flowy_collaboration::entities::text_block_info::TextBlockInfo; use flowy_folder::event_map::FolderEvent::*; use flowy_folder_data_model::entities::view::{RepeatedViewId, ViewId}; use flowy_folder_data_model::entities::workspace::WorkspaceId; @@ -161,14 +161,14 @@ pub async fn delete_view(sdk: &FlowySDKTest, view_ids: Vec) { .await; } -pub async fn open_document(sdk: &FlowySDKTest, view_id: &str) -> BlockInfo { +pub async fn open_document(sdk: &FlowySDKTest, view_id: &str) -> TextBlockInfo { let view_id: ViewId = view_id.into(); FolderEventBuilder::new(sdk.clone()) .event(SetLatestView) .payload(view_id) .async_send() .await - .parse::() + .parse::() } pub async fn read_trash(sdk: &FlowySDKTest) -> RepeatedTrash { diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index bc3418f441..e4298b54e7 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 crate::helper::*; -use flowy_collaboration::entities::{document_info::BlockInfo, revision::RevisionState}; +use flowy_collaboration::entities::{revision::RevisionState, text_block_info::TextBlockInfo}; use flowy_folder::{errors::ErrorCode, services::folder_editor::ClientFolderEditor}; use flowy_folder_data_model::entities::{ app::{App, RepeatedApp}, @@ -58,7 +58,7 @@ pub struct FolderTest { pub app: App, pub view: View, pub trash: Vec, - pub document_info: Option, + pub document_info: Option, // pub folder_editor: } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs index bfc2fc1568..e74ad692d3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs @@ -44,7 +44,7 @@ impl GridBuilder { let grid_meta = GridMeta { grid_id: self.grid_id, fields: self.fields, - rows: self.rows, + blocks: vec![], }; // let _ = check_rows(&self.fields, &self.rows)?; diff --git a/frontend/rust-lib/flowy-net/src/http_server/document.rs b/frontend/rust-lib/flowy-net/src/http_server/document.rs index da33e1b8a0..1016e903e4 100644 --- a/frontend/rust-lib/flowy-net/src/http_server/document.rs +++ b/frontend/rust-lib/flowy-net/src/http_server/document.rs @@ -3,7 +3,9 @@ use crate::{ request::{HttpRequestBuilder, ResponseMiddleware}, }; use flowy_block::BlockCloudService; -use flowy_collaboration::entities::document_info::{BlockId, BlockInfo, CreateBlockParams, ResetBlockParams}; +use flowy_collaboration::entities::text_block_info::{ + CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo, +}; use flowy_error::FlowyError; use http_flowy::response::FlowyResponse; use lazy_static::lazy_static; @@ -21,26 +23,26 @@ impl BlockHttpCloudService { } impl BlockCloudService for BlockHttpCloudService { - fn create_block(&self, token: &str, params: CreateBlockParams) -> FutureResult<(), FlowyError> { + fn create_block(&self, token: &str, params: CreateTextBlockParams) -> FutureResult<(), FlowyError> { let token = token.to_owned(); let url = self.config.doc_url(); FutureResult::new(async move { create_document_request(&token, params, &url).await }) } - fn read_block(&self, token: &str, params: BlockId) -> FutureResult, FlowyError> { + fn read_block(&self, token: &str, params: TextBlockId) -> FutureResult, FlowyError> { let token = token.to_owned(); let url = self.config.doc_url(); FutureResult::new(async move { read_document_request(&token, params, &url).await }) } - fn update_block(&self, token: &str, params: ResetBlockParams) -> FutureResult<(), FlowyError> { + fn update_block(&self, token: &str, params: ResetTextBlockParams) -> FutureResult<(), FlowyError> { let token = token.to_owned(); let url = self.config.doc_url(); FutureResult::new(async move { reset_doc_request(&token, params, &url).await }) } } -pub async fn create_document_request(token: &str, params: CreateBlockParams, url: &str) -> Result<(), FlowyError> { +pub async fn create_document_request(token: &str, params: CreateTextBlockParams, url: &str) -> Result<(), FlowyError> { let _ = request_builder() .post(&url.to_owned()) .header(HEADER_TOKEN, token) @@ -50,7 +52,11 @@ pub async fn create_document_request(token: &str, params: CreateBlockParams, url Ok(()) } -pub async fn read_document_request(token: &str, params: BlockId, url: &str) -> Result, FlowyError> { +pub async fn read_document_request( + token: &str, + params: TextBlockId, + url: &str, +) -> Result, FlowyError> { let doc = request_builder() .get(&url.to_owned()) .header(HEADER_TOKEN, token) @@ -61,7 +67,7 @@ pub async fn read_document_request(token: &str, params: BlockId, url: &str) -> R Ok(doc) } -pub async fn reset_doc_request(token: &str, params: ResetBlockParams, url: &str) -> Result<(), FlowyError> { +pub async fn reset_doc_request(token: &str, params: ResetTextBlockParams, url: &str) -> Result<(), FlowyError> { let _ = request_builder() .patch(&url.to_owned()) .header(HEADER_TOKEN, token) diff --git a/frontend/rust-lib/flowy-net/src/local_server/persistence.rs b/frontend/rust-lib/flowy-net/src/local_server/persistence.rs index db23fbf2ef..89e107e44f 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/persistence.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/persistence.rs @@ -1,5 +1,5 @@ use flowy_collaboration::{ - entities::{document_info::BlockInfo, folder_info::FolderInfo}, + entities::{folder_info::FolderInfo, text_block_info::TextBlockInfo}, errors::CollaborateError, protobuf::{RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB}, server_document::*, @@ -111,7 +111,7 @@ impl FolderCloudPersistence for LocalDocumentCloudPersistence { } impl DocumentCloudPersistence for LocalDocumentCloudPersistence { - fn read_document(&self, doc_id: &str) -> BoxResultFuture { + fn read_document(&self, doc_id: &str) -> BoxResultFuture { let storage = self.storage.clone(); let doc_id = doc_id.to_owned(); Box::pin(async move { @@ -127,7 +127,7 @@ impl DocumentCloudPersistence for LocalDocumentCloudPersistence { &self, doc_id: &str, repeated_revision: RepeatedRevisionPB, - ) -> BoxResultFuture, CollaborateError> { + ) -> BoxResultFuture, CollaborateError> { let doc_id = doc_id.to_owned(); let storage = self.storage.clone(); Box::pin(async move { diff --git a/frontend/rust-lib/flowy-net/src/local_server/server.rs b/frontend/rust-lib/flowy-net/src/local_server/server.rs index 3bfa30e06a..b25bf9429f 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/server.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/server.rs @@ -4,7 +4,7 @@ use bytes::Bytes; use flowy_collaboration::{ client_document::default::initial_quill_delta_string, entities::{ - document_info::{BlockId, BlockInfo, CreateBlockParams, ResetBlockParams}, + text_block_info::{CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo}, ws_data::{ClientRevisionWSData, ClientRevisionWSDataType}, }, errors::CollaborateError, @@ -413,12 +413,12 @@ impl UserCloudService for LocalServer { } impl BlockCloudService for LocalServer { - fn create_block(&self, _token: &str, _params: CreateBlockParams) -> FutureResult<(), FlowyError> { + fn create_block(&self, _token: &str, _params: CreateTextBlockParams) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } - fn read_block(&self, _token: &str, params: BlockId) -> FutureResult, FlowyError> { - let doc = BlockInfo { + fn read_block(&self, _token: &str, params: TextBlockId) -> FutureResult, FlowyError> { + let doc = TextBlockInfo { block_id: params.value, text: initial_quill_delta_string(), rev_id: 0, @@ -427,7 +427,7 @@ impl BlockCloudService for LocalServer { FutureResult::new(async { Ok(Some(doc)) }) } - fn update_block(&self, _token: &str, _params: ResetBlockParams) -> FutureResult<(), FlowyError> { + fn update_block(&self, _token: &str, _params: ResetTextBlockParams) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } } diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs index e648bd9e66..5550395229 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs @@ -1,5 +1,5 @@ use bytes::Bytes; -use flowy_block::BlockManager; +use flowy_block::TextBlockManager; use flowy_collaboration::client_document::default::initial_quill_delta_string; use flowy_collaboration::entities::revision::RepeatedRevision; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; @@ -32,7 +32,7 @@ impl FolderDepsResolver { user_session: Arc, server_config: &ClientServerConfiguration, ws_conn: &Arc, - block_manager: &Arc, + text_block_manager: &Arc, grid_manager: &Arc, ) -> Arc { let user: Arc = Arc::new(WorkspaceUserImpl(user_session.clone())); @@ -43,7 +43,7 @@ impl FolderDepsResolver { Some(local_server) => local_server, }; - let view_data_processor = make_view_data_processor(block_manager.clone(), grid_manager.clone()); + let view_data_processor = make_view_data_processor(text_block_manager.clone(), grid_manager.clone()); let folder_manager = Arc::new(FolderManager::new(user.clone(), cloud_service, database, view_data_processor, web_socket).await); @@ -60,10 +60,13 @@ impl FolderDepsResolver { } } -fn make_view_data_processor(block_manager: Arc, grid_manager: Arc) -> ViewDataProcessorMap { +fn make_view_data_processor( + text_block_manager: Arc, + grid_manager: Arc, +) -> ViewDataProcessorMap { let mut map: HashMap> = HashMap::new(); - let block_data_impl = BlockManagerViewDataImpl(block_manager); + let block_data_impl = BlockManagerViewDataImpl(text_block_manager); map.insert(block_data_impl.data_type(), Arc::new(block_data_impl)); let grid_data_impl = GridManagerViewDataImpl(grid_manager); @@ -130,45 +133,45 @@ impl WSMessageReceiver for FolderWSMessageReceiverImpl { } } -struct BlockManagerViewDataImpl(Arc); +struct BlockManagerViewDataImpl(Arc); impl ViewDataProcessor for BlockManagerViewDataImpl { fn initialize(&self) -> FutureResult<(), FlowyError> { - let block_manager = self.0.clone(); - FutureResult::new(async move { block_manager.init() }) + let manager = self.0.clone(); + FutureResult::new(async move { manager.init() }) } fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FutureResult<(), FlowyError> { - let block_manager = self.0.clone(); + let manager = self.0.clone(); let view_id = view_id.to_string(); FutureResult::new(async move { - let _ = block_manager.create_block(view_id, repeated_revision).await?; + let _ = manager.create_block(view_id, repeated_revision).await?; Ok(()) }) } fn delete_container(&self, view_id: &str) -> FutureResult<(), FlowyError> { - let block_manager = self.0.clone(); + let manager = self.0.clone(); let view_id = view_id.to_string(); FutureResult::new(async move { - let _ = block_manager.delete_block(view_id)?; + let _ = manager.delete_block(view_id)?; Ok(()) }) } fn close_container(&self, view_id: &str) -> FutureResult<(), FlowyError> { - let block_manager = self.0.clone(); + let manager = self.0.clone(); let view_id = view_id.to_string(); FutureResult::new(async move { - let _ = block_manager.close_block(view_id)?; + let _ = manager.close_block(view_id)?; Ok(()) }) } fn delta_str(&self, view_id: &str) -> FutureResult { let view_id = view_id.to_string(); - let block_manager = self.0.clone(); + let manager = self.0.clone(); FutureResult::new(async move { - let editor = block_manager.open_block(view_id).await?; + let editor = manager.open_block(view_id).await?; let delta_str = editor.delta_str().await?; Ok(delta_str) }) diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/mod.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/mod.rs index c0a84d8d94..cac82f9c56 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/mod.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/mod.rs @@ -1,10 +1,10 @@ -mod block_deps; mod folder_deps; mod grid_deps; +mod text_block_deps; mod user_deps; mod util; -pub use block_deps::*; pub use folder_deps::*; pub use grid_deps::*; +pub use text_block_deps::*; pub use user_deps::*; diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/block_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/text_block_deps.rs similarity index 85% rename from frontend/rust-lib/flowy-sdk/src/deps_resolve/block_deps.rs rename to frontend/rust-lib/flowy-sdk/src/deps_resolve/text_block_deps.rs index f8c97d133c..5482bbe546 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/block_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/text_block_deps.rs @@ -1,7 +1,7 @@ use bytes::Bytes; use flowy_block::{ errors::{internal_error, FlowyError}, - BlockCloudService, BlockManager, BlockUser, + BlockCloudService, TextBlockManager, TextBlockUser, }; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; @@ -16,22 +16,22 @@ use lib_infra::future::BoxResultFuture; use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage}; use std::{convert::TryInto, path::Path, sync::Arc}; -pub struct BlockDepsResolver(); -impl BlockDepsResolver { +pub struct TextBlockDepsResolver(); +impl TextBlockDepsResolver { pub fn resolve( local_server: Option>, ws_conn: Arc, user_session: Arc, server_config: &ClientServerConfiguration, - ) -> Arc { + ) -> Arc { let user = Arc::new(BlockUserImpl(user_session)); - let rev_web_socket = Arc::new(BlockWebSocket(ws_conn.clone())); + let rev_web_socket = Arc::new(TextBlockWebSocket(ws_conn.clone())); let cloud_service: Arc = match local_server { None => Arc::new(BlockHttpCloudService::new(server_config.clone())), Some(local_server) => local_server, }; - let manager = Arc::new(BlockManager::new(cloud_service, user, rev_web_socket)); + let manager = Arc::new(TextBlockManager::new(cloud_service, user, rev_web_socket)); let receiver = Arc::new(DocumentWSMessageReceiverImpl(manager.clone())); ws_conn.add_ws_message_receiver(receiver).unwrap(); @@ -40,7 +40,7 @@ impl BlockDepsResolver { } struct BlockUserImpl(Arc); -impl BlockUser for BlockUserImpl { +impl TextBlockUser for BlockUserImpl { fn user_dir(&self) -> Result { let dir = self.0.user_dir().map_err(|e| FlowyError::unauthorized().context(e))?; @@ -64,8 +64,8 @@ impl BlockUser for BlockUserImpl { } } -struct BlockWebSocket(Arc); -impl RevisionWebSocket for BlockWebSocket { +struct TextBlockWebSocket(Arc); +impl RevisionWebSocket for TextBlockWebSocket { fn send(&self, data: ClientRevisionWSData) -> BoxResultFuture<(), FlowyError> { let bytes: Bytes = data.try_into().unwrap(); let msg = WebSocketRawMessage { @@ -90,7 +90,7 @@ impl RevisionWebSocket for BlockWebSocket { } } -struct DocumentWSMessageReceiverImpl(Arc); +struct DocumentWSMessageReceiverImpl(Arc); impl WSMessageReceiver for DocumentWSMessageReceiverImpl { fn source(&self) -> WSChannel { WSChannel::Document diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index 7c254acd66..7acf14952e 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -3,7 +3,7 @@ pub mod module; pub use flowy_net::get_client_server_configuration; use crate::deps_resolve::*; -use flowy_block::BlockManager; +use flowy_block::TextBlockManager; use flowy_folder::{errors::FlowyError, manager::FolderManager}; use flowy_grid::manager::GridManager; use flowy_net::ClientServerConfiguration; @@ -88,7 +88,7 @@ pub struct FlowySDK { #[allow(dead_code)] config: FlowySDKConfig, pub user_session: Arc, - pub block_manager: Arc, + pub text_block_manager: Arc, pub folder_manager: Arc, pub grid_manager: Arc, pub dispatcher: Arc, @@ -103,9 +103,9 @@ impl FlowySDK { tracing::debug!("🔥 {:?}", config); let runtime = tokio_default_runtime().unwrap(); let (local_server, ws_conn) = mk_local_server(&config.server_config); - let (user_session, block_manager, folder_manager, local_server, grid_manager) = runtime.block_on(async { + let (user_session, text_block_manager, folder_manager, local_server, grid_manager) = runtime.block_on(async { let user_session = mk_user_session(&config, &local_server, &config.server_config); - let block_manager = BlockDepsResolver::resolve( + let text_block_manager = TextBlockDepsResolver::resolve( local_server.clone(), ws_conn.clone(), user_session.clone(), @@ -119,7 +119,7 @@ impl FlowySDK { user_session.clone(), &config.server_config, &ws_conn, - &block_manager, + &text_block_manager, &grid_manager, ) .await; @@ -128,11 +128,23 @@ impl FlowySDK { local_server.run(); } ws_conn.init().await; - (user_session, block_manager, folder_manager, local_server, grid_manager) + ( + user_session, + text_block_manager, + folder_manager, + local_server, + grid_manager, + ) }); let dispatcher = Arc::new(EventDispatcher::construct(runtime, || { - mk_modules(&ws_conn, &folder_manager, &grid_manager, &user_session, &block_manager) + mk_modules( + &ws_conn, + &folder_manager, + &grid_manager, + &user_session, + &text_block_manager, + ) })); _start_listening(&dispatcher, &ws_conn, &user_session, &folder_manager); @@ -140,7 +152,7 @@ impl FlowySDK { Self { config, user_session, - block_manager, + text_block_manager, folder_manager, grid_manager, dispatcher, diff --git a/frontend/rust-lib/flowy-sdk/src/module.rs b/frontend/rust-lib/flowy-sdk/src/module.rs index 18bf44a2af..0a3fb1f87a 100644 --- a/frontend/rust-lib/flowy-sdk/src/module.rs +++ b/frontend/rust-lib/flowy-sdk/src/module.rs @@ -1,4 +1,4 @@ -use flowy_block::BlockManager; +use flowy_block::TextBlockManager; use flowy_folder::manager::FolderManager; use flowy_grid::manager::GridManager; use flowy_net::ws::connection::FlowyWebSocketConnect; @@ -11,14 +11,20 @@ pub fn mk_modules( folder_manager: &Arc, grid_manager: &Arc, user_session: &Arc, - block_manager: &Arc, + text_block_manager: &Arc, ) -> Vec { let user_module = mk_user_module(user_session.clone()); let folder_module = mk_folder_module(folder_manager.clone()); let network_module = mk_network_module(ws_conn.clone()); let grid_module = mk_grid_module(grid_manager.clone()); - let block_module = mk_block_module(block_manager.clone()); - vec![user_module, folder_module, network_module, grid_module, block_module] + let text_block_module = mk_text_block_module(text_block_manager.clone()); + vec![ + user_module, + folder_module, + network_module, + grid_module, + text_block_module, + ] } fn mk_user_module(user_session: Arc) -> Module { @@ -37,6 +43,6 @@ fn mk_grid_module(grid_manager: Arc) -> Module { flowy_grid::event_map::create(grid_manager) } -fn mk_block_module(block_manager: Arc) -> Module { - flowy_block::event_map::create(block_manager) +fn mk_text_block_module(text_block_manager: Arc) -> Module { + flowy_block::event_map::create(text_block_manager) } diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/folder_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/folder_rev_impl.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs index 7bcbc30fdd..6c3ee45f37 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs @@ -1,9 +1,14 @@ -mod sql_impl; +mod folder_rev_impl; +mod grid_rev_impl; +mod text_block_rev_impl; + +pub use folder_rev_impl::*; +pub use grid_rev_impl::*; +pub use text_block_rev_impl::*; + use crate::RevisionRecord; use diesel::SqliteConnection; use flowy_collaboration::entities::revision::RevisionRange; -pub use sql_impl::*; - use flowy_error::FlowyResult; use std::fmt::Debug; diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/sql_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/text_block_rev_impl.rs similarity index 98% rename from frontend/rust-lib/flowy-sync/src/cache/disk/sql_impl.rs rename to frontend/rust-lib/flowy-sync/src/cache/disk/text_block_rev_impl.rs index e985a98bd8..d7b56034c3 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/sql_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/text_block_rev_impl.rs @@ -14,12 +14,12 @@ use flowy_database::{ use flowy_error::{internal_error, FlowyError, FlowyResult}; use std::sync::Arc; -pub struct SQLitePersistence { +pub struct SQLiteTextBlockRevisionPersistence { user_id: String, pub(crate) pool: Arc, } -impl RevisionDiskCache for SQLitePersistence { +impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { type Error = FlowyError; fn create_revision_records( @@ -83,7 +83,7 @@ impl RevisionDiskCache for SQLitePersistence { } } -impl SQLitePersistence { +impl SQLiteTextBlockRevisionPersistence { pub(crate) fn new(user_id: &str, pool: Arc) -> Self { Self { user_id: user_id.to_owned(), diff --git a/frontend/rust-lib/flowy-sync/src/cache/mod.rs b/frontend/rust-lib/flowy-sync/src/cache/mod.rs index a6b5be4102..9ef6fb7da0 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/mod.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/mod.rs @@ -1,325 +1,2 @@ -mod disk; -mod memory; - -use crate::cache::{ - disk::{RevisionChangeset, RevisionDiskCache, RevisionTableState, SQLitePersistence}, - memory::{RevisionMemoryCache, RevisionMemoryCacheDelegate}, -}; - -use flowy_collaboration::entities::revision::{Revision, RevisionRange, RevisionState}; -use flowy_database::ConnectionPool; -use flowy_error::{internal_error, FlowyError, FlowyResult}; - -use crate::RevisionCompact; -use std::collections::VecDeque; -use std::{borrow::Cow, sync::Arc}; -use tokio::sync::RwLock; -use tokio::task::spawn_blocking; - -pub const REVISION_WRITE_INTERVAL_IN_MILLIS: u64 = 600; - -pub struct RevisionPersistence { - user_id: String, - object_id: String, - disk_cache: Arc>, - memory_cache: Arc, - sync_seq: RwLock, -} -impl RevisionPersistence { - pub fn new(user_id: &str, object_id: &str, pool: Arc) -> RevisionPersistence { - let disk_cache = Arc::new(SQLitePersistence::new(user_id, pool)); - let memory_cache = Arc::new(RevisionMemoryCache::new(object_id, Arc::new(disk_cache.clone()))); - let object_id = object_id.to_owned(); - let user_id = user_id.to_owned(); - let sync_seq = RwLock::new(RevisionSyncSequence::new()); - Self { - user_id, - object_id, - disk_cache, - memory_cache, - sync_seq, - } - } - - /// Save the revision that comes from remote to disk. - #[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, object_id=%self.object_id), err)] - pub(crate) async fn add_ack_revision(&self, revision: &Revision) -> FlowyResult<()> { - tracing::Span::current().record("rev_id", &revision.rev_id); - self.add(revision.clone(), RevisionState::Ack, true).await - } - - /// Append the revision that already existed in the local DB state to sync sequence - #[tracing::instrument(level = "trace", skip(self), fields(rev_id, object_id=%self.object_id), err)] - pub(crate) async fn sync_revision(&self, revision: &Revision) -> FlowyResult<()> { - tracing::Span::current().record("rev_id", &revision.rev_id); - self.add(revision.clone(), RevisionState::Sync, false).await?; - self.sync_seq.write().await.add(revision.rev_id)?; - Ok(()) - } - - /// Save the revision to disk and append it to the end of the sync sequence. - #[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, compact_range, object_id=%self.object_id), err)] - pub(crate) async fn add_sync_revision(&self, revision: &Revision) -> FlowyResult - where - C: RevisionCompact, - { - let result = self.sync_seq.read().await.compact(); - match result { - None => { - tracing::Span::current().record("rev_id", &revision.rev_id); - self.add(revision.clone(), RevisionState::Sync, true).await?; - self.sync_seq.write().await.add(revision.rev_id)?; - Ok(revision.rev_id) - } - Some((range, mut compact_seq)) => { - tracing::Span::current().record("compact_range", &format!("{}", range).as_str()); - let mut revisions = self.revisions_in_range(&range).await?; - if range.to_rev_ids().len() != revisions.len() { - debug_assert_eq!(range.to_rev_ids().len(), revisions.len()); - } - - // append the new revision - revisions.push(revision.clone()); - - // compact multiple revisions into one - let compact_revision = C::compact_revisions(&self.user_id, &self.object_id, revisions)?; - let rev_id = compact_revision.rev_id; - tracing::Span::current().record("rev_id", &rev_id); - - // insert new revision - compact_seq.push_back(rev_id); - - // replace the revisions in range with compact revision - self.compact(&range, compact_revision).await?; - debug_assert_eq!(self.sync_seq.read().await.len(), compact_seq.len()); - self.sync_seq.write().await.reset(compact_seq); - Ok(rev_id) - } - } - } - - /// Remove the revision with rev_id from the sync sequence. - pub(crate) async fn ack_revision(&self, rev_id: i64) -> FlowyResult<()> { - if self.sync_seq.write().await.ack(&rev_id).is_ok() { - self.memory_cache.ack(&rev_id).await; - } - Ok(()) - } - - pub(crate) async fn next_sync_revision(&self) -> FlowyResult> { - match self.sync_seq.read().await.next_rev_id() { - None => Ok(None), - Some(rev_id) => Ok(self.get(rev_id).await.map(|record| record.revision)), - } - } - - /// The cache gets reset while it conflicts with the remote revisions. - #[tracing::instrument(level = "trace", skip(self, revisions), err)] - pub(crate) async fn reset(&self, revisions: Vec) -> FlowyResult<()> { - let records = revisions - .to_vec() - .into_iter() - .map(|revision| RevisionRecord { - revision, - state: RevisionState::Sync, - write_to_disk: false, - }) - .collect::>(); - - let _ = self - .disk_cache - .delete_and_insert_records(&self.object_id, None, records.clone())?; - let _ = self.memory_cache.reset_with_revisions(records).await; - self.sync_seq.write().await.clear(); - Ok(()) - } - - async fn add(&self, revision: Revision, state: RevisionState, write_to_disk: bool) -> FlowyResult<()> { - if self.memory_cache.contains(&revision.rev_id) { - tracing::warn!("Duplicate revision: {}:{}-{:?}", self.object_id, revision.rev_id, state); - return Ok(()); - } - let record = RevisionRecord { - revision, - state, - write_to_disk, - }; - - self.memory_cache.add(Cow::Owned(record)).await; - Ok(()) - } - - async fn compact(&self, range: &RevisionRange, new_revision: Revision) -> FlowyResult<()> { - self.memory_cache.remove_with_range(range); - let rev_ids = range.to_rev_ids(); - let _ = self - .disk_cache - .delete_revision_records(&self.object_id, Some(rev_ids))?; - - self.add(new_revision, RevisionState::Sync, true).await?; - Ok(()) - } - - pub async fn get(&self, rev_id: i64) -> Option { - match self.memory_cache.get(&rev_id).await { - None => match self - .disk_cache - .read_revision_records(&self.object_id, Some(vec![rev_id])) - { - Ok(mut records) => { - let record = records.pop()?; - assert!(records.is_empty()); - Some(record) - } - Err(e) => { - tracing::error!("{}", e); - None - } - }, - Some(revision) => Some(revision), - } - } - - pub fn batch_get(&self, doc_id: &str) -> FlowyResult> { - self.disk_cache.read_revision_records(doc_id, None) - } - - // Read the revision which rev_id >= range.start && rev_id <= range.end - pub async fn revisions_in_range(&self, range: &RevisionRange) -> FlowyResult> { - let range = range.clone(); - let mut records = self.memory_cache.get_with_range(&range).await?; - let range_len = range.len() as usize; - if records.len() != range_len { - let disk_cache = self.disk_cache.clone(); - let object_id = self.object_id.clone(); - records = spawn_blocking(move || disk_cache.read_revision_records_with_range(&object_id, &range)) - .await - .map_err(internal_error)??; - - if records.len() != range_len { - // #[cfg(debug_assertions)] - // records.iter().for_each(|record| { - // let delta = PlainDelta::from_bytes(&record.revision.delta_data).unwrap(); - // tracing::trace!("{}", delta.to_string()); - // }); - tracing::error!("Expect revision len {},but receive {}", range_len, records.len()); - } - } - Ok(records - .into_iter() - .map(|record| record.revision) - .collect::>()) - } -} - -pub fn mk_revision_disk_cache( - user_id: &str, - pool: Arc, -) -> Arc> { - Arc::new(SQLitePersistence::new(user_id, pool)) -} - -impl RevisionMemoryCacheDelegate for Arc { - #[tracing::instrument(level = "trace", skip(self, records), fields(checkpoint_result), err)] - fn checkpoint_tick(&self, mut records: Vec) -> FlowyResult<()> { - let conn = &*self.pool.get().map_err(internal_error)?; - records.retain(|record| record.write_to_disk); - if !records.is_empty() { - tracing::Span::current().record( - "checkpoint_result", - &format!("{} records were saved", records.len()).as_str(), - ); - let _ = self.create_revision_records(records, conn)?; - } - Ok(()) - } - - fn receive_ack(&self, object_id: &str, rev_id: i64) { - let changeset = RevisionChangeset { - object_id: object_id.to_string(), - rev_id: rev_id.into(), - state: RevisionTableState::Ack, - }; - match self.update_revision_record(vec![changeset]) { - Ok(_) => {} - Err(e) => tracing::error!("{}", e), - } - } -} - -#[derive(Clone, Debug)] -pub struct RevisionRecord { - pub revision: Revision, - pub state: RevisionState, - pub write_to_disk: bool, -} - -impl RevisionRecord { - pub fn ack(&mut self) { - self.state = RevisionState::Ack; - } -} - -#[derive(Default)] -struct RevisionSyncSequence(VecDeque); -impl RevisionSyncSequence { - fn new() -> Self { - RevisionSyncSequence::default() - } - - fn add(&mut self, new_rev_id: i64) -> FlowyResult<()> { - // The last revision's rev_id must be greater than the new one. - if let Some(rev_id) = self.0.back() { - if *rev_id >= new_rev_id { - return Err( - FlowyError::internal().context(format!("The new revision's id must be greater than {}", rev_id)) - ); - } - } - self.0.push_back(new_rev_id); - Ok(()) - } - - fn ack(&mut self, rev_id: &i64) -> FlowyResult<()> { - let cur_rev_id = self.0.front().cloned(); - if let Some(pop_rev_id) = cur_rev_id { - if &pop_rev_id != rev_id { - let desc = format!( - "The ack rev_id:{} is not equal to the current rev_id:{}", - rev_id, pop_rev_id - ); - return Err(FlowyError::internal().context(desc)); - } - let _ = self.0.pop_front(); - } - Ok(()) - } - - fn next_rev_id(&self) -> Option { - self.0.front().cloned() - } - - fn reset(&mut self, new_seq: VecDeque) { - self.0 = new_seq; - } - - fn clear(&mut self) { - self.0.clear(); - } - - fn len(&self) -> usize { - self.0.len() - } - - // Compact the rev_ids into one except the current synchronizing rev_id. - fn compact(&self) -> Option<(RevisionRange, VecDeque)> { - self.next_rev_id()?; - - let mut new_seq = self.0.clone(); - let mut drained = new_seq.drain(1..).collect::>(); - - let start = drained.pop_front()?; - let end = drained.pop_back().unwrap_or(start); - Some((RevisionRange { start, end }, new_seq)) - } -} +pub(crate) mod disk; +pub(crate) mod memory; diff --git a/frontend/rust-lib/flowy-sync/src/lib.rs b/frontend/rust-lib/flowy-sync/src/lib.rs index 16cc05d2c7..05e60c00e0 100644 --- a/frontend/rust-lib/flowy-sync/src/lib.rs +++ b/frontend/rust-lib/flowy-sync/src/lib.rs @@ -1,11 +1,13 @@ mod cache; mod conflict_resolve; mod rev_manager; +mod rev_persistence; mod ws_manager; pub use cache::*; pub use conflict_resolve::*; pub use rev_manager::*; +pub use rev_persistence::*; pub use ws_manager::*; #[macro_use] diff --git a/frontend/rust-lib/flowy-sync/src/rev_persistence.rs b/frontend/rust-lib/flowy-sync/src/rev_persistence.rs new file mode 100644 index 0000000000..428e708916 --- /dev/null +++ b/frontend/rust-lib/flowy-sync/src/rev_persistence.rs @@ -0,0 +1,322 @@ +use crate::cache::{ + disk::{RevisionChangeset, RevisionDiskCache, RevisionTableState, SQLiteTextBlockRevisionPersistence}, + memory::{RevisionMemoryCache, RevisionMemoryCacheDelegate}, +}; + +use flowy_collaboration::entities::revision::{Revision, RevisionRange, RevisionState}; +use flowy_database::ConnectionPool; +use flowy_error::{internal_error, FlowyError, FlowyResult}; + +use crate::RevisionCompact; +use std::collections::VecDeque; +use std::{borrow::Cow, sync::Arc}; +use tokio::sync::RwLock; +use tokio::task::spawn_blocking; + +pub const REVISION_WRITE_INTERVAL_IN_MILLIS: u64 = 600; + +pub struct RevisionPersistence { + user_id: String, + object_id: String, + disk_cache: Arc>, + memory_cache: Arc, + sync_seq: RwLock, +} +impl RevisionPersistence { + pub fn new(user_id: &str, object_id: &str, pool: Arc) -> RevisionPersistence { + let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(user_id, pool)); + let memory_cache = Arc::new(RevisionMemoryCache::new(object_id, Arc::new(disk_cache.clone()))); + let object_id = object_id.to_owned(); + let user_id = user_id.to_owned(); + let sync_seq = RwLock::new(RevisionSyncSequence::new()); + Self { + user_id, + object_id, + disk_cache, + memory_cache, + sync_seq, + } + } + + /// Save the revision that comes from remote to disk. + #[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, object_id=%self.object_id), err)] + pub(crate) async fn add_ack_revision(&self, revision: &Revision) -> FlowyResult<()> { + tracing::Span::current().record("rev_id", &revision.rev_id); + self.add(revision.clone(), RevisionState::Ack, true).await + } + + /// Append the revision that already existed in the local DB state to sync sequence + #[tracing::instrument(level = "trace", skip(self), fields(rev_id, object_id=%self.object_id), err)] + pub(crate) async fn sync_revision(&self, revision: &Revision) -> FlowyResult<()> { + tracing::Span::current().record("rev_id", &revision.rev_id); + self.add(revision.clone(), RevisionState::Sync, false).await?; + self.sync_seq.write().await.add(revision.rev_id)?; + Ok(()) + } + + /// Save the revision to disk and append it to the end of the sync sequence. + #[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, compact_range, object_id=%self.object_id), err)] + pub(crate) async fn add_sync_revision(&self, revision: &Revision) -> FlowyResult + where + C: RevisionCompact, + { + let result = self.sync_seq.read().await.compact(); + match result { + None => { + tracing::Span::current().record("rev_id", &revision.rev_id); + self.add(revision.clone(), RevisionState::Sync, true).await?; + self.sync_seq.write().await.add(revision.rev_id)?; + Ok(revision.rev_id) + } + Some((range, mut compact_seq)) => { + tracing::Span::current().record("compact_range", &format!("{}", range).as_str()); + let mut revisions = self.revisions_in_range(&range).await?; + if range.to_rev_ids().len() != revisions.len() { + debug_assert_eq!(range.to_rev_ids().len(), revisions.len()); + } + + // append the new revision + revisions.push(revision.clone()); + + // compact multiple revisions into one + let compact_revision = C::compact_revisions(&self.user_id, &self.object_id, revisions)?; + let rev_id = compact_revision.rev_id; + tracing::Span::current().record("rev_id", &rev_id); + + // insert new revision + compact_seq.push_back(rev_id); + + // replace the revisions in range with compact revision + self.compact(&range, compact_revision).await?; + debug_assert_eq!(self.sync_seq.read().await.len(), compact_seq.len()); + self.sync_seq.write().await.reset(compact_seq); + Ok(rev_id) + } + } + } + + /// Remove the revision with rev_id from the sync sequence. + pub(crate) async fn ack_revision(&self, rev_id: i64) -> FlowyResult<()> { + if self.sync_seq.write().await.ack(&rev_id).is_ok() { + self.memory_cache.ack(&rev_id).await; + } + Ok(()) + } + + pub(crate) async fn next_sync_revision(&self) -> FlowyResult> { + match self.sync_seq.read().await.next_rev_id() { + None => Ok(None), + Some(rev_id) => Ok(self.get(rev_id).await.map(|record| record.revision)), + } + } + + /// The cache gets reset while it conflicts with the remote revisions. + #[tracing::instrument(level = "trace", skip(self, revisions), err)] + pub(crate) async fn reset(&self, revisions: Vec) -> FlowyResult<()> { + let records = revisions + .to_vec() + .into_iter() + .map(|revision| RevisionRecord { + revision, + state: RevisionState::Sync, + write_to_disk: false, + }) + .collect::>(); + + let _ = self + .disk_cache + .delete_and_insert_records(&self.object_id, None, records.clone())?; + let _ = self.memory_cache.reset_with_revisions(records).await; + self.sync_seq.write().await.clear(); + Ok(()) + } + + async fn add(&self, revision: Revision, state: RevisionState, write_to_disk: bool) -> FlowyResult<()> { + if self.memory_cache.contains(&revision.rev_id) { + tracing::warn!("Duplicate revision: {}:{}-{:?}", self.object_id, revision.rev_id, state); + return Ok(()); + } + let record = RevisionRecord { + revision, + state, + write_to_disk, + }; + + self.memory_cache.add(Cow::Owned(record)).await; + Ok(()) + } + + async fn compact(&self, range: &RevisionRange, new_revision: Revision) -> FlowyResult<()> { + self.memory_cache.remove_with_range(range); + let rev_ids = range.to_rev_ids(); + let _ = self + .disk_cache + .delete_revision_records(&self.object_id, Some(rev_ids))?; + + self.add(new_revision, RevisionState::Sync, true).await?; + Ok(()) + } + + pub async fn get(&self, rev_id: i64) -> Option { + match self.memory_cache.get(&rev_id).await { + None => match self + .disk_cache + .read_revision_records(&self.object_id, Some(vec![rev_id])) + { + Ok(mut records) => { + let record = records.pop()?; + assert!(records.is_empty()); + Some(record) + } + Err(e) => { + tracing::error!("{}", e); + None + } + }, + Some(revision) => Some(revision), + } + } + + pub fn batch_get(&self, doc_id: &str) -> FlowyResult> { + self.disk_cache.read_revision_records(doc_id, None) + } + + // Read the revision which rev_id >= range.start && rev_id <= range.end + pub async fn revisions_in_range(&self, range: &RevisionRange) -> FlowyResult> { + let range = range.clone(); + let mut records = self.memory_cache.get_with_range(&range).await?; + let range_len = range.len() as usize; + if records.len() != range_len { + let disk_cache = self.disk_cache.clone(); + let object_id = self.object_id.clone(); + records = spawn_blocking(move || disk_cache.read_revision_records_with_range(&object_id, &range)) + .await + .map_err(internal_error)??; + + if records.len() != range_len { + // #[cfg(debug_assertions)] + // records.iter().for_each(|record| { + // let delta = PlainDelta::from_bytes(&record.revision.delta_data).unwrap(); + // tracing::trace!("{}", delta.to_string()); + // }); + tracing::error!("Expect revision len {},but receive {}", range_len, records.len()); + } + } + Ok(records + .into_iter() + .map(|record| record.revision) + .collect::>()) + } +} + +pub fn mk_revision_disk_cache( + user_id: &str, + pool: Arc, +) -> Arc> { + Arc::new(SQLiteTextBlockRevisionPersistence::new(user_id, pool)) +} + +impl RevisionMemoryCacheDelegate for Arc { + #[tracing::instrument(level = "trace", skip(self, records), fields(checkpoint_result), err)] + fn checkpoint_tick(&self, mut records: Vec) -> FlowyResult<()> { + let conn = &*self.pool.get().map_err(internal_error)?; + records.retain(|record| record.write_to_disk); + if !records.is_empty() { + tracing::Span::current().record( + "checkpoint_result", + &format!("{} records were saved", records.len()).as_str(), + ); + let _ = self.create_revision_records(records, conn)?; + } + Ok(()) + } + + fn receive_ack(&self, object_id: &str, rev_id: i64) { + let changeset = RevisionChangeset { + object_id: object_id.to_string(), + rev_id: rev_id.into(), + state: RevisionTableState::Ack, + }; + match self.update_revision_record(vec![changeset]) { + Ok(_) => {} + Err(e) => tracing::error!("{}", e), + } + } +} + +#[derive(Clone, Debug)] +pub struct RevisionRecord { + pub revision: Revision, + pub state: RevisionState, + pub write_to_disk: bool, +} + +impl RevisionRecord { + pub fn ack(&mut self) { + self.state = RevisionState::Ack; + } +} + +#[derive(Default)] +struct RevisionSyncSequence(VecDeque); +impl RevisionSyncSequence { + fn new() -> Self { + RevisionSyncSequence::default() + } + + fn add(&mut self, new_rev_id: i64) -> FlowyResult<()> { + // The last revision's rev_id must be greater than the new one. + if let Some(rev_id) = self.0.back() { + if *rev_id >= new_rev_id { + return Err( + FlowyError::internal().context(format!("The new revision's id must be greater than {}", rev_id)) + ); + } + } + self.0.push_back(new_rev_id); + Ok(()) + } + + fn ack(&mut self, rev_id: &i64) -> FlowyResult<()> { + let cur_rev_id = self.0.front().cloned(); + if let Some(pop_rev_id) = cur_rev_id { + if &pop_rev_id != rev_id { + let desc = format!( + "The ack rev_id:{} is not equal to the current rev_id:{}", + rev_id, pop_rev_id + ); + return Err(FlowyError::internal().context(desc)); + } + let _ = self.0.pop_front(); + } + Ok(()) + } + + fn next_rev_id(&self) -> Option { + self.0.front().cloned() + } + + fn reset(&mut self, new_seq: VecDeque) { + self.0 = new_seq; + } + + fn clear(&mut self) { + self.0.clear(); + } + + fn len(&self) -> usize { + self.0.len() + } + + // Compact the rev_ids into one except the current synchronizing rev_id. + fn compact(&self) -> Option<(RevisionRange, VecDeque)> { + self.next_rev_id()?; + + let mut new_seq = self.0.clone(); + let mut drained = new_seq.drain(1..).collect::>(); + + let start = drained.pop_front()?; + let end = drained.pop_back().unwrap_or(start); + Some((RevisionRange { start, end }, new_seq)) + } +} diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs new file mode 100644 index 0000000000..23f07e3efb --- /dev/null +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -0,0 +1,115 @@ +use crate::entities::revision::{md5, RepeatedRevision, Revision}; +use crate::errors::{internal_error, CollaborateError, CollaborateResult}; +use crate::util::{cal_diff, make_delta_from_revisions}; +use flowy_grid_data_model::entities::{BlockMeta, RowMeta, RowOrder}; +use lib_infra::uuid; +use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; +use std::sync::Arc; + +pub type BlockMetaDelta = PlainTextDelta; +pub type BlockDeltaBuilder = PlainTextDeltaBuilder; + +pub struct BlockMetaPad { + pub(crate) block_meta: Arc, + pub(crate) delta: BlockMetaDelta, +} + +impl BlockMetaPad { + pub fn from_delta(delta: BlockMetaDelta) -> CollaborateResult { + let s = delta.to_str()?; + let block_delta: BlockMeta = serde_json::from_str(&s).map_err(|e| { + CollaborateError::internal().context(format!("Deserialize delta to block meta failed: {}", e)) + })?; + + Ok(Self { + block_meta: Arc::new(block_delta), + delta, + }) + } + + pub fn from_revisions(_grid_id: &str, revisions: Vec) -> CollaborateResult { + let block_delta: BlockMetaDelta = make_delta_from_revisions::(revisions)?; + Self::from_delta(block_delta) + } + + pub fn create_row(&mut self, row: RowMeta) -> CollaborateResult> { + self.modify(|grid| { + grid.rows.push(row); + Ok(Some(())) + }) + } + + pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { + self.modify(|grid| { + grid.rows.retain(|row| !row_ids.contains(&row.id)); + Ok(Some(())) + }) + } + + pub fn md5(&self) -> String { + md5(&self.delta.to_bytes()) + } + + pub fn delta_str(&self) -> String { + self.delta.to_delta_str() + } + + pub fn modify(&mut self, f: F) -> CollaborateResult> + where + F: FnOnce(&mut BlockMeta) -> CollaborateResult>, + { + let cloned_meta = self.block_meta.clone(); + match f(Arc::make_mut(&mut self.block_meta))? { + None => Ok(None), + Some(_) => { + let old = json_from_grid(&cloned_meta)?; + let new = json_from_grid(&self.block_meta)?; + match cal_diff::(old, new) { + None => Ok(None), + Some(delta) => { + self.delta = self.delta.compose(&delta)?; + Ok(Some(BlockMetaChange { delta, md5: self.md5() })) + } + } + } + } + } +} + +fn json_from_grid(block_meta: &Arc) -> CollaborateResult { + let json = serde_json::to_string(block_meta) + .map_err(|err| internal_error(format!("Serialize grid to json str failed. {:?}", err)))?; + Ok(json) +} + +pub struct BlockMetaChange { + pub delta: BlockMetaDelta, + /// md5: the md5 of the grid after applying the change. + pub md5: String, +} + +pub fn make_block_meta_delta(block_meta: &BlockMeta) -> BlockMetaDelta { + let json = serde_json::to_string(&block_meta).unwrap(); + PlainTextDeltaBuilder::new().insert(&json).build() +} + +pub fn make_block_meta_revisions(user_id: &str, block_meta: &BlockMeta) -> RepeatedRevision { + let delta = make_block_meta_delta(block_meta); + let bytes = delta.to_bytes(); + let revision = Revision::initial_revision(user_id, &block_meta.block_id, bytes); + revision.into() +} + +impl std::default::Default for BlockMetaPad { + fn default() -> Self { + let block_meta = BlockMeta { + block_id: uuid(), + rows: vec![], + }; + let delta = make_block_meta_delta(&block_meta); + BlockMetaPad { + block_meta: Arc::new(block_meta), + delta, + } + } +} diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 32b3f968b3..f61cd484fc 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -33,7 +33,7 @@ impl GridMetaPad { pub fn create_row(&mut self, row: RowMeta) -> CollaborateResult> { self.modify_grid(|grid| { - grid.rows.push(row); + // grid.rows.push(row); Ok(Some(())) }) } @@ -47,7 +47,7 @@ impl GridMetaPad { pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { self.modify_grid(|grid| { - grid.rows.retain(|row| !row_ids.contains(&row.id)); + // grid.rows.retain(|row| !row_ids.contains(&row.id)); Ok(Some(())) }) } @@ -74,17 +74,17 @@ impl GridMetaPad { .map(FieldOrder::from) .collect::>(); - let row_orders = self - .grid_meta - .rows - .iter() - .map(RowOrder::from) - .collect::>(); + // let row_orders = self + // .grid_meta + // .rows + // .iter() + // .map(RowOrder::from) + // .collect::>(); Grid { id: "".to_string(), field_orders, - row_orders, + row_orders: vec![], } } @@ -147,7 +147,7 @@ impl std::default::Default for GridMetaPad { let grid = GridMeta { grid_id: uuid(), fields: vec![], - rows: vec![], + blocks: vec![], }; let delta = make_grid_delta(&grid); GridMetaPad { diff --git a/shared-lib/flowy-collaboration/src/client_grid/mod.rs b/shared-lib/flowy-collaboration/src/client_grid/mod.rs index ee5a403a57..8ecb671968 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/mod.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/mod.rs @@ -1,3 +1,5 @@ +mod block_pad; mod grid_pad; +pub use block_pad::*; pub use grid_pad::*; diff --git a/shared-lib/flowy-collaboration/src/entities/mod.rs b/shared-lib/flowy-collaboration/src/entities/mod.rs index f31f9e34fd..8989125677 100644 --- a/shared-lib/flowy-collaboration/src/entities/mod.rs +++ b/shared-lib/flowy-collaboration/src/entities/mod.rs @@ -1,5 +1,5 @@ -pub mod document_info; pub mod folder_info; pub mod parser; pub mod revision; +pub mod text_block_info; pub mod ws_data; diff --git a/shared-lib/flowy-collaboration/src/entities/document_info.rs b/shared-lib/flowy-collaboration/src/entities/text_block_info.rs similarity index 78% rename from shared-lib/flowy-collaboration/src/entities/document_info.rs rename to shared-lib/flowy-collaboration/src/entities/text_block_info.rs index f80ab97207..c325fdad07 100644 --- a/shared-lib/flowy-collaboration/src/entities/document_info.rs +++ b/shared-lib/flowy-collaboration/src/entities/text_block_info.rs @@ -6,7 +6,7 @@ use flowy_derive::ProtoBuf; use lib_ot::{errors::OTError, rich_text::RichTextDelta}; #[derive(ProtoBuf, Default, Debug, Clone)] -pub struct CreateBlockParams { +pub struct CreateTextBlockParams { #[pb(index = 1)] pub id: String, @@ -15,7 +15,7 @@ pub struct CreateBlockParams { } #[derive(ProtoBuf, Default, Debug, Clone, Eq, PartialEq)] -pub struct BlockInfo { +pub struct TextBlockInfo { #[pb(index = 1)] pub block_id: String, @@ -29,14 +29,14 @@ pub struct BlockInfo { pub base_rev_id: i64, } -impl BlockInfo { +impl TextBlockInfo { pub fn delta(&self) -> Result { let delta = RichTextDelta::from_bytes(&self.text)?; Ok(delta) } } -impl std::convert::TryFrom for BlockInfo { +impl std::convert::TryFrom for TextBlockInfo { type Error = CollaborateError; fn try_from(revision: Revision) -> Result { @@ -48,7 +48,7 @@ impl std::convert::TryFrom for BlockInfo { let delta = RichTextDelta::from_bytes(&revision.delta_data)?; let doc_json = delta.to_delta_str(); - Ok(BlockInfo { + Ok(TextBlockInfo { block_id: revision.object_id, text: doc_json, rev_id: revision.rev_id, @@ -58,7 +58,7 @@ impl std::convert::TryFrom for BlockInfo { } #[derive(ProtoBuf, Default, Debug, Clone)] -pub struct ResetBlockParams { +pub struct ResetTextBlockParams { #[pb(index = 1)] pub block_id: String, @@ -67,7 +67,7 @@ pub struct ResetBlockParams { } #[derive(ProtoBuf, Default, Debug, Clone)] -pub struct BlockDelta { +pub struct TextBlockDelta { #[pb(index = 1)] pub block_id: String, @@ -88,30 +88,30 @@ pub struct NewDocUser { } #[derive(ProtoBuf, Default, Debug, Clone)] -pub struct BlockId { +pub struct TextBlockId { #[pb(index = 1)] pub value: String, } -impl AsRef for BlockId { +impl AsRef for TextBlockId { fn as_ref(&self) -> &str { &self.value } } -impl std::convert::From for BlockId { +impl std::convert::From for TextBlockId { fn from(value: String) -> Self { - BlockId { value } + TextBlockId { value } } } -impl std::convert::From for String { - fn from(block_id: BlockId) -> Self { +impl std::convert::From for String { + fn from(block_id: TextBlockId) -> Self { block_id.value } } -impl std::convert::From<&String> for BlockId { +impl std::convert::From<&String> for TextBlockId { fn from(s: &String) -> Self { - BlockId { value: s.to_owned() } + TextBlockId { value: s.to_owned() } } } diff --git a/shared-lib/flowy-collaboration/src/protobuf/model/mod.rs b/shared-lib/flowy-collaboration/src/protobuf/model/mod.rs index 137466e63f..d0627984e3 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/model/mod.rs +++ b/shared-lib/flowy-collaboration/src/protobuf/model/mod.rs @@ -7,8 +7,8 @@ pub use folder_info::*; mod ws_data; pub use ws_data::*; +mod text_block_info; +pub use text_block_info::*; + mod revision; pub use revision::*; - -mod document_info; -pub use document_info::*; diff --git a/shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs b/shared-lib/flowy-collaboration/src/protobuf/model/text_block_info.rs similarity index 85% rename from shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs rename to shared-lib/flowy-collaboration/src/protobuf/model/text_block_info.rs index 28b3eb6bde..1e44767a92 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs +++ b/shared-lib/flowy-collaboration/src/protobuf/model/text_block_info.rs @@ -17,14 +17,14 @@ #![allow(trivial_casts)] #![allow(unused_imports)] #![allow(unused_results)] -//! Generated file from `document_info.proto` +//! Generated file from `text_block_info.proto` /// Generated files are compatible only with the same version /// of protobuf runtime. // const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; #[derive(PartialEq,Clone,Default)] -pub struct CreateBlockParams { +pub struct CreateTextBlockParams { // message fields pub id: ::std::string::String, pub revisions: ::protobuf::SingularPtrField, @@ -33,14 +33,14 @@ pub struct CreateBlockParams { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a CreateBlockParams { - fn default() -> &'a CreateBlockParams { - ::default_instance() +impl<'a> ::std::default::Default for &'a CreateTextBlockParams { + fn default() -> &'a CreateTextBlockParams { + ::default_instance() } } -impl CreateBlockParams { - pub fn new() -> CreateBlockParams { +impl CreateTextBlockParams { + pub fn new() -> CreateTextBlockParams { ::std::default::Default::default() } @@ -104,7 +104,7 @@ impl CreateBlockParams { } } -impl ::protobuf::Message for CreateBlockParams { +impl ::protobuf::Message for CreateTextBlockParams { fn is_initialized(&self) -> bool { for v in &self.revisions { if !v.is_initialized() { @@ -187,8 +187,8 @@ impl ::protobuf::Message for CreateBlockParams { Self::descriptor_static() } - fn new() -> CreateBlockParams { - CreateBlockParams::new() + fn new() -> CreateTextBlockParams { + CreateTextBlockParams::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -197,29 +197,29 @@ impl ::protobuf::Message for CreateBlockParams { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "id", - |m: &CreateBlockParams| { &m.id }, - |m: &mut CreateBlockParams| { &mut m.id }, + |m: &CreateTextBlockParams| { &m.id }, + |m: &mut CreateTextBlockParams| { &mut m.id }, )); fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "revisions", - |m: &CreateBlockParams| { &m.revisions }, - |m: &mut CreateBlockParams| { &mut m.revisions }, + |m: &CreateTextBlockParams| { &m.revisions }, + |m: &mut CreateTextBlockParams| { &mut m.revisions }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "CreateBlockParams", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CreateTextBlockParams", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static CreateBlockParams { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(CreateBlockParams::new) + fn default_instance() -> &'static CreateTextBlockParams { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CreateTextBlockParams::new) } } -impl ::protobuf::Clear for CreateBlockParams { +impl ::protobuf::Clear for CreateTextBlockParams { fn clear(&mut self) { self.id.clear(); self.revisions.clear(); @@ -227,20 +227,20 @@ impl ::protobuf::Clear for CreateBlockParams { } } -impl ::std::fmt::Debug for CreateBlockParams { +impl ::std::fmt::Debug for CreateTextBlockParams { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for CreateBlockParams { +impl ::protobuf::reflect::ProtobufValue for CreateTextBlockParams { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } #[derive(PartialEq,Clone,Default)] -pub struct BlockInfo { +pub struct TextBlockInfo { // message fields pub block_id: ::std::string::String, pub text: ::std::string::String, @@ -251,14 +251,14 @@ pub struct BlockInfo { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a BlockInfo { - fn default() -> &'a BlockInfo { - ::default_instance() +impl<'a> ::std::default::Default for &'a TextBlockInfo { + fn default() -> &'a TextBlockInfo { + ::default_instance() } } -impl BlockInfo { - pub fn new() -> BlockInfo { +impl TextBlockInfo { + pub fn new() -> TextBlockInfo { ::std::default::Default::default() } @@ -345,7 +345,7 @@ impl BlockInfo { } } -impl ::protobuf::Message for BlockInfo { +impl ::protobuf::Message for TextBlockInfo { fn is_initialized(&self) -> bool { true } @@ -446,8 +446,8 @@ impl ::protobuf::Message for BlockInfo { Self::descriptor_static() } - fn new() -> BlockInfo { - BlockInfo::new() + fn new() -> TextBlockInfo { + TextBlockInfo::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -456,39 +456,39 @@ impl ::protobuf::Message for BlockInfo { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "block_id", - |m: &BlockInfo| { &m.block_id }, - |m: &mut BlockInfo| { &mut m.block_id }, + |m: &TextBlockInfo| { &m.block_id }, + |m: &mut TextBlockInfo| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "text", - |m: &BlockInfo| { &m.text }, - |m: &mut BlockInfo| { &mut m.text }, + |m: &TextBlockInfo| { &m.text }, + |m: &mut TextBlockInfo| { &mut m.text }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( "rev_id", - |m: &BlockInfo| { &m.rev_id }, - |m: &mut BlockInfo| { &mut m.rev_id }, + |m: &TextBlockInfo| { &m.rev_id }, + |m: &mut TextBlockInfo| { &mut m.rev_id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( "base_rev_id", - |m: &BlockInfo| { &m.base_rev_id }, - |m: &mut BlockInfo| { &mut m.base_rev_id }, + |m: &TextBlockInfo| { &m.base_rev_id }, + |m: &mut TextBlockInfo| { &mut m.base_rev_id }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "BlockInfo", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "TextBlockInfo", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static BlockInfo { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(BlockInfo::new) + fn default_instance() -> &'static TextBlockInfo { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(TextBlockInfo::new) } } -impl ::protobuf::Clear for BlockInfo { +impl ::protobuf::Clear for TextBlockInfo { fn clear(&mut self) { self.block_id.clear(); self.text.clear(); @@ -498,20 +498,20 @@ impl ::protobuf::Clear for BlockInfo { } } -impl ::std::fmt::Debug for BlockInfo { +impl ::std::fmt::Debug for TextBlockInfo { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for BlockInfo { +impl ::protobuf::reflect::ProtobufValue for TextBlockInfo { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } #[derive(PartialEq,Clone,Default)] -pub struct ResetBlockParams { +pub struct ResetTextBlockParams { // message fields pub block_id: ::std::string::String, pub revisions: ::protobuf::SingularPtrField, @@ -520,14 +520,14 @@ pub struct ResetBlockParams { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a ResetBlockParams { - fn default() -> &'a ResetBlockParams { - ::default_instance() +impl<'a> ::std::default::Default for &'a ResetTextBlockParams { + fn default() -> &'a ResetTextBlockParams { + ::default_instance() } } -impl ResetBlockParams { - pub fn new() -> ResetBlockParams { +impl ResetTextBlockParams { + pub fn new() -> ResetTextBlockParams { ::std::default::Default::default() } @@ -591,7 +591,7 @@ impl ResetBlockParams { } } -impl ::protobuf::Message for ResetBlockParams { +impl ::protobuf::Message for ResetTextBlockParams { fn is_initialized(&self) -> bool { for v in &self.revisions { if !v.is_initialized() { @@ -674,8 +674,8 @@ impl ::protobuf::Message for ResetBlockParams { Self::descriptor_static() } - fn new() -> ResetBlockParams { - ResetBlockParams::new() + fn new() -> ResetTextBlockParams { + ResetTextBlockParams::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -684,29 +684,29 @@ impl ::protobuf::Message for ResetBlockParams { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "block_id", - |m: &ResetBlockParams| { &m.block_id }, - |m: &mut ResetBlockParams| { &mut m.block_id }, + |m: &ResetTextBlockParams| { &m.block_id }, + |m: &mut ResetTextBlockParams| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "revisions", - |m: &ResetBlockParams| { &m.revisions }, - |m: &mut ResetBlockParams| { &mut m.revisions }, + |m: &ResetTextBlockParams| { &m.revisions }, + |m: &mut ResetTextBlockParams| { &mut m.revisions }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "ResetBlockParams", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "ResetTextBlockParams", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static ResetBlockParams { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(ResetBlockParams::new) + fn default_instance() -> &'static ResetTextBlockParams { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(ResetTextBlockParams::new) } } -impl ::protobuf::Clear for ResetBlockParams { +impl ::protobuf::Clear for ResetTextBlockParams { fn clear(&mut self) { self.block_id.clear(); self.revisions.clear(); @@ -714,20 +714,20 @@ impl ::protobuf::Clear for ResetBlockParams { } } -impl ::std::fmt::Debug for ResetBlockParams { +impl ::std::fmt::Debug for ResetTextBlockParams { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for ResetBlockParams { +impl ::protobuf::reflect::ProtobufValue for ResetTextBlockParams { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } #[derive(PartialEq,Clone,Default)] -pub struct BlockDelta { +pub struct TextBlockDelta { // message fields pub block_id: ::std::string::String, pub delta_str: ::std::string::String, @@ -736,14 +736,14 @@ pub struct BlockDelta { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a BlockDelta { - fn default() -> &'a BlockDelta { - ::default_instance() +impl<'a> ::std::default::Default for &'a TextBlockDelta { + fn default() -> &'a TextBlockDelta { + ::default_instance() } } -impl BlockDelta { - pub fn new() -> BlockDelta { +impl TextBlockDelta { + pub fn new() -> TextBlockDelta { ::std::default::Default::default() } @@ -800,7 +800,7 @@ impl BlockDelta { } } -impl ::protobuf::Message for BlockDelta { +impl ::protobuf::Message for TextBlockDelta { fn is_initialized(&self) -> bool { true } @@ -875,8 +875,8 @@ impl ::protobuf::Message for BlockDelta { Self::descriptor_static() } - fn new() -> BlockDelta { - BlockDelta::new() + fn new() -> TextBlockDelta { + TextBlockDelta::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -885,29 +885,29 @@ impl ::protobuf::Message for BlockDelta { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "block_id", - |m: &BlockDelta| { &m.block_id }, - |m: &mut BlockDelta| { &mut m.block_id }, + |m: &TextBlockDelta| { &m.block_id }, + |m: &mut TextBlockDelta| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "delta_str", - |m: &BlockDelta| { &m.delta_str }, - |m: &mut BlockDelta| { &mut m.delta_str }, + |m: &TextBlockDelta| { &m.delta_str }, + |m: &mut TextBlockDelta| { &mut m.delta_str }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "BlockDelta", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "TextBlockDelta", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static BlockDelta { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(BlockDelta::new) + fn default_instance() -> &'static TextBlockDelta { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(TextBlockDelta::new) } } -impl ::protobuf::Clear for BlockDelta { +impl ::protobuf::Clear for TextBlockDelta { fn clear(&mut self) { self.block_id.clear(); self.delta_str.clear(); @@ -915,13 +915,13 @@ impl ::protobuf::Clear for BlockDelta { } } -impl ::std::fmt::Debug for BlockDelta { +impl ::std::fmt::Debug for TextBlockDelta { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for BlockDelta { +impl ::protobuf::reflect::ProtobufValue for TextBlockDelta { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -1164,7 +1164,7 @@ impl ::protobuf::reflect::ProtobufValue for NewDocUser { } #[derive(PartialEq,Clone,Default)] -pub struct BlockId { +pub struct TextBlockId { // message fields pub value: ::std::string::String, // special fields @@ -1172,14 +1172,14 @@ pub struct BlockId { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a BlockId { - fn default() -> &'a BlockId { - ::default_instance() +impl<'a> ::std::default::Default for &'a TextBlockId { + fn default() -> &'a TextBlockId { + ::default_instance() } } -impl BlockId { - pub fn new() -> BlockId { +impl TextBlockId { + pub fn new() -> TextBlockId { ::std::default::Default::default() } @@ -1210,7 +1210,7 @@ impl BlockId { } } -impl ::protobuf::Message for BlockId { +impl ::protobuf::Message for TextBlockId { fn is_initialized(&self) -> bool { true } @@ -1276,8 +1276,8 @@ impl ::protobuf::Message for BlockId { Self::descriptor_static() } - fn new() -> BlockId { - BlockId::new() + fn new() -> TextBlockId { + TextBlockId::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -1286,57 +1286,57 @@ impl ::protobuf::Message for BlockId { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "value", - |m: &BlockId| { &m.value }, - |m: &mut BlockId| { &mut m.value }, + |m: &TextBlockId| { &m.value }, + |m: &mut TextBlockId| { &mut m.value }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "BlockId", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "TextBlockId", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static BlockId { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(BlockId::new) + fn default_instance() -> &'static TextBlockId { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(TextBlockId::new) } } -impl ::protobuf::Clear for BlockId { +impl ::protobuf::Clear for TextBlockId { fn clear(&mut self) { self.value.clear(); self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for BlockId { +impl ::std::fmt::Debug for TextBlockId { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for BlockId { +impl ::protobuf::reflect::ProtobufValue for TextBlockId { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x13document_info.proto\x1a\x0erevision.proto\"T\n\x11CreateBlockParam\ - s\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12/\n\trevisions\x18\x02\ - \x20\x01(\x0b2\x11.RepeatedRevisionR\trevisions\"q\n\tBlockInfo\x12\x19\ - \n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x12\n\x04text\x18\x02\ - \x20\x01(\tR\x04text\x12\x15\n\x06rev_id\x18\x03\x20\x01(\x03R\x05revId\ - \x12\x1e\n\x0bbase_rev_id\x18\x04\x20\x01(\x03R\tbaseRevId\"^\n\x10Reset\ - BlockParams\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12/\n\ - \trevisions\x18\x02\x20\x01(\x0b2\x11.RepeatedRevisionR\trevisions\"D\n\ - \nBlockDelta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\ - \x1b\n\tdelta_str\x18\x02\x20\x01(\tR\x08deltaStr\"S\n\nNewDocUser\x12\ - \x17\n\x07user_id\x18\x01\x20\x01(\tR\x06userId\x12\x15\n\x06rev_id\x18\ - \x02\x20\x01(\x03R\x05revId\x12\x15\n\x06doc_id\x18\x03\x20\x01(\tR\x05d\ - ocId\"\x1f\n\x07BlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05valueb\ - \x06proto3\ + \n\x15text_block_info.proto\x1a\x0erevision.proto\"X\n\x15CreateTextBloc\ + kParams\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12/\n\trevisions\x18\ + \x02\x20\x01(\x0b2\x11.RepeatedRevisionR\trevisions\"u\n\rTextBlockInfo\ + \x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x12\n\x04text\ + \x18\x02\x20\x01(\tR\x04text\x12\x15\n\x06rev_id\x18\x03\x20\x01(\x03R\ + \x05revId\x12\x1e\n\x0bbase_rev_id\x18\x04\x20\x01(\x03R\tbaseRevId\"b\n\ + \x14ResetTextBlockParams\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07bl\ + ockId\x12/\n\trevisions\x18\x02\x20\x01(\x0b2\x11.RepeatedRevisionR\trev\ + isions\"H\n\x0eTextBlockDelta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\ + \x07blockId\x12\x1b\n\tdelta_str\x18\x02\x20\x01(\tR\x08deltaStr\"S\n\nN\ + ewDocUser\x12\x17\n\x07user_id\x18\x01\x20\x01(\tR\x06userId\x12\x15\n\ + \x06rev_id\x18\x02\x20\x01(\x03R\x05revId\x12\x15\n\x06doc_id\x18\x03\ + \x20\x01(\tR\x05docId\"#\n\x0bTextBlockId\x12\x14\n\x05value\x18\x01\x20\ + \x01(\tR\x05valueb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-collaboration/src/protobuf/proto/document_info.proto b/shared-lib/flowy-collaboration/src/protobuf/proto/text_block_info.proto similarity index 76% rename from shared-lib/flowy-collaboration/src/protobuf/proto/document_info.proto rename to shared-lib/flowy-collaboration/src/protobuf/proto/text_block_info.proto index 9190b581a5..70717c4d2b 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/proto/document_info.proto +++ b/shared-lib/flowy-collaboration/src/protobuf/proto/text_block_info.proto @@ -1,21 +1,21 @@ syntax = "proto3"; import "revision.proto"; -message CreateBlockParams { +message CreateTextBlockParams { string id = 1; RepeatedRevision revisions = 2; } -message BlockInfo { +message TextBlockInfo { string block_id = 1; string text = 2; int64 rev_id = 3; int64 base_rev_id = 4; } -message ResetBlockParams { +message ResetTextBlockParams { string block_id = 1; RepeatedRevision revisions = 2; } -message BlockDelta { +message TextBlockDelta { string block_id = 1; string delta_str = 2; } @@ -24,6 +24,6 @@ message NewDocUser { int64 rev_id = 2; string doc_id = 3; } -message BlockId { +message TextBlockId { string value = 1; } diff --git a/shared-lib/flowy-collaboration/src/server_document/document_manager.rs b/shared-lib/flowy-collaboration/src/server_document/document_manager.rs index 37c3bf4f6a..8a5b5f7304 100644 --- a/shared-lib/flowy-collaboration/src/server_document/document_manager.rs +++ b/shared-lib/flowy-collaboration/src/server_document/document_manager.rs @@ -1,5 +1,5 @@ use crate::{ - entities::{document_info::BlockInfo, ws_data::ServerRevisionWSDataBuilder}, + entities::{text_block_info::TextBlockInfo, ws_data::ServerRevisionWSDataBuilder}, errors::{internal_error, CollaborateError, CollaborateResult}, protobuf::{ClientRevisionWSData, RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB}, server_document::document_pad::ServerDocument, @@ -18,13 +18,13 @@ use tokio::{ }; pub trait DocumentCloudPersistence: Send + Sync + Debug { - fn read_document(&self, doc_id: &str) -> BoxResultFuture; + fn read_document(&self, doc_id: &str) -> BoxResultFuture; fn create_document( &self, doc_id: &str, repeated_revision: RepeatedRevisionPB, - ) -> BoxResultFuture, CollaborateError>; + ) -> BoxResultFuture, CollaborateError>; fn read_document_revisions( &self, @@ -181,7 +181,7 @@ impl ServerDocumentManager { } } - async fn create_document_handler(&self, doc: BlockInfo) -> Result, CollaborateError> { + async fn create_document_handler(&self, doc: TextBlockInfo) -> Result, CollaborateError> { let persistence = self.persistence.clone(); let handle = spawn_blocking(|| OpenDocumentHandler::new(doc, persistence)) .await @@ -205,7 +205,7 @@ struct OpenDocumentHandler { } impl OpenDocumentHandler { - fn new(doc: BlockInfo, persistence: Arc) -> Result { + fn new(doc: TextBlockInfo, persistence: Arc) -> Result { let doc_id = doc.block_id.clone(); let (sender, receiver) = mpsc::channel(1000); let users = DashMap::new(); diff --git a/shared-lib/flowy-collaboration/src/util.rs b/shared-lib/flowy-collaboration/src/util.rs index 6953949961..a3ea7b136e 100644 --- a/shared-lib/flowy-collaboration/src/util.rs +++ b/shared-lib/flowy-collaboration/src/util.rs @@ -1,13 +1,13 @@ use crate::{ entities::{ - document_info::BlockInfo, folder_info::{FolderDelta, FolderInfo}, revision::{RepeatedRevision, Revision}, + text_block_info::TextBlockInfo, }, errors::{CollaborateError, CollaborateResult}, protobuf::{ - BlockInfo as BlockInfoPB, FolderInfo as FolderInfoPB, RepeatedRevision as RepeatedRevisionPB, - Revision as RevisionPB, + FolderInfo as FolderInfoPB, RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB, + TextBlockInfo as TextBlockInfoPB, }, }; use dissimilar::Chunk; @@ -202,11 +202,11 @@ pub fn make_folder_pb_from_revisions_pb( pub fn make_document_info_from_revisions_pb( doc_id: &str, revisions: RepeatedRevisionPB, -) -> Result, CollaborateError> { +) -> Result, CollaborateError> { match make_document_info_pb_from_revisions_pb(doc_id, revisions)? { None => Ok(None), Some(pb) => { - let document_info: BlockInfo = pb.try_into().map_err(|e| { + let document_info: TextBlockInfo = pb.try_into().map_err(|e| { CollaborateError::internal().context(format!("Deserialize document info from pb failed: {}", e)) })?; Ok(Some(document_info)) @@ -218,7 +218,7 @@ pub fn make_document_info_from_revisions_pb( pub fn make_document_info_pb_from_revisions_pb( doc_id: &str, mut revisions: RepeatedRevisionPB, -) -> Result, CollaborateError> { +) -> Result, CollaborateError> { let revisions = revisions.take_items(); if revisions.is_empty() { return Ok(None); @@ -240,7 +240,7 @@ pub fn make_document_info_pb_from_revisions_pb( } let text = document_delta.to_delta_str(); - let mut block_info = BlockInfoPB::new(); + let mut block_info = TextBlockInfoPB::new(); block_info.set_block_id(doc_id.to_owned()); block_info.set_text(text); block_info.set_base_rev_id(base_rev_id); 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 ad85fe636b..e5f5c189cc 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,8 +1,6 @@ use crate::entities::{Field, RowMeta}; -use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; -use serde::{Deserialize, Serialize}; +use flowy_derive::ProtoBuf; use std::collections::HashMap; -use strum_macros::{Display, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 36; pub const DEFAULT_FIELD_WIDTH: i32 = 150; diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 22abf8905d..5fbd55ffa6 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -1,4 +1,3 @@ -use crate::entities::Row; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -16,14 +15,26 @@ pub struct GridMeta { pub fields: Vec, #[pb(index = 3)] - pub rows: Vec, + pub blocks: Vec, } #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] -pub struct GridBlock { +pub struct Block { #[pb(index = 1)] pub id: String, + #[pb(index = 2)] + pub start_row_index: i32, + + #[pb(index = 3)] + pub row_count: i32, +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +pub struct BlockMeta { + #[pb(index = 1)] + pub block_id: String, + #[pb(index = 2)] pub rows: Vec, } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index deaa2a75c2..a542d09d7d 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -28,7 +28,7 @@ pub struct GridMeta { // message fields pub grid_id: ::std::string::String, pub fields: ::protobuf::RepeatedField, - pub rows: ::protobuf::RepeatedField, + pub blocks: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -96,29 +96,29 @@ impl GridMeta { ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new()) } - // repeated .RowMeta rows = 3; + // repeated .Block blocks = 3; - pub fn get_rows(&self) -> &[RowMeta] { - &self.rows + pub fn get_blocks(&self) -> &[Block] { + &self.blocks } - pub fn clear_rows(&mut self) { - self.rows.clear(); + pub fn clear_blocks(&mut self) { + self.blocks.clear(); } // Param is passed by value, moved - pub fn set_rows(&mut self, v: ::protobuf::RepeatedField) { - self.rows = v; + pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { + self.blocks = v; } // Mutable pointer to the field. - pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.rows + pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.blocks } // Take field - pub fn take_rows(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new()) + pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) } } @@ -129,7 +129,7 @@ impl ::protobuf::Message for GridMeta { return false; } }; - for v in &self.rows { + for v in &self.blocks { if !v.is_initialized() { return false; } @@ -148,7 +148,7 @@ impl ::protobuf::Message for GridMeta { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.fields)?; }, 3 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -169,7 +169,7 @@ impl ::protobuf::Message for GridMeta { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; - for value in &self.rows { + for value in &self.blocks { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; @@ -187,7 +187,7 @@ impl ::protobuf::Message for GridMeta { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; }; - for v in &self.rows { + for v in &self.blocks { os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -240,10 +240,10 @@ impl ::protobuf::Message for GridMeta { |m: &GridMeta| { &m.fields }, |m: &mut GridMeta| { &mut m.fields }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "rows", - |m: &GridMeta| { &m.rows }, - |m: &mut GridMeta| { &mut m.rows }, + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "blocks", + |m: &GridMeta| { &m.blocks }, + |m: &mut GridMeta| { &mut m.blocks }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "GridMeta", @@ -263,7 +263,7 @@ impl ::protobuf::Clear for GridMeta { fn clear(&mut self) { self.grid_id.clear(); self.fields.clear(); - self.rows.clear(); + self.blocks.clear(); self.unknown_fields.clear(); } } @@ -281,23 +281,24 @@ impl ::protobuf::reflect::ProtobufValue for GridMeta { } #[derive(PartialEq,Clone,Default)] -pub struct GridBlock { +pub struct Block { // message fields pub id: ::std::string::String, - pub rows: ::protobuf::RepeatedField, + pub start_row_index: i32, + pub row_count: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a GridBlock { - fn default() -> &'a GridBlock { - ::default_instance() +impl<'a> ::std::default::Default for &'a Block { + fn default() -> &'a Block { + ::default_instance() } } -impl GridBlock { - pub fn new() -> GridBlock { +impl Block { + pub fn new() -> Block { ::std::default::Default::default() } @@ -327,6 +328,234 @@ impl GridBlock { ::std::mem::replace(&mut self.id, ::std::string::String::new()) } + // int32 start_row_index = 2; + + + pub fn get_start_row_index(&self) -> i32 { + self.start_row_index + } + pub fn clear_start_row_index(&mut self) { + self.start_row_index = 0; + } + + // Param is passed by value, moved + pub fn set_start_row_index(&mut self, v: i32) { + self.start_row_index = v; + } + + // int32 row_count = 3; + + + pub fn get_row_count(&self) -> i32 { + self.row_count + } + pub fn clear_row_count(&mut self) { + self.row_count = 0; + } + + // Param is passed by value, moved + pub fn set_row_count(&mut self, v: i32) { + self.row_count = v; + } +} + +impl ::protobuf::Message for Block { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.start_row_index = tmp; + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.row_count = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + if self.start_row_index != 0 { + my_size += ::protobuf::rt::value_size(2, self.start_row_index, ::protobuf::wire_format::WireTypeVarint); + } + if self.row_count != 0 { + my_size += ::protobuf::rt::value_size(3, self.row_count, ::protobuf::wire_format::WireTypeVarint); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + if self.start_row_index != 0 { + os.write_int32(2, self.start_row_index)?; + } + if self.row_count != 0 { + os.write_int32(3, self.row_count)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Block { + Block::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &Block| { &m.id }, + |m: &mut Block| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "start_row_index", + |m: &Block| { &m.start_row_index }, + |m: &mut Block| { &mut m.start_row_index }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "row_count", + |m: &Block| { &m.row_count }, + |m: &mut Block| { &mut m.row_count }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Block", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Block { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Block::new) + } +} + +impl ::protobuf::Clear for Block { + fn clear(&mut self) { + self.id.clear(); + self.start_row_index = 0; + self.row_count = 0; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Block { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Block { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct BlockMeta { + // message fields + pub block_id: ::std::string::String, + pub rows: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a BlockMeta { + fn default() -> &'a BlockMeta { + ::default_instance() + } +} + +impl BlockMeta { + pub fn new() -> BlockMeta { + ::std::default::Default::default() + } + + // string block_id = 1; + + + pub fn get_block_id(&self) -> &str { + &self.block_id + } + pub fn clear_block_id(&mut self) { + self.block_id.clear(); + } + + // Param is passed by value, moved + pub fn set_block_id(&mut self, v: ::std::string::String) { + self.block_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id + } + + // Take field + pub fn take_block_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) + } + // repeated .RowMeta rows = 2; @@ -353,7 +582,7 @@ impl GridBlock { } } -impl ::protobuf::Message for GridBlock { +impl ::protobuf::Message for BlockMeta { fn is_initialized(&self) -> bool { for v in &self.rows { if !v.is_initialized() { @@ -368,7 +597,7 @@ impl ::protobuf::Message for GridBlock { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, 2 => { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; @@ -385,8 +614,8 @@ impl ::protobuf::Message for GridBlock { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.block_id); } for value in &self.rows { let len = value.compute_size(); @@ -398,8 +627,8 @@ impl ::protobuf::Message for GridBlock { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; + if !self.block_id.is_empty() { + os.write_string(1, &self.block_id)?; } for v in &self.rows { os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; @@ -436,8 +665,8 @@ impl ::protobuf::Message for GridBlock { Self::descriptor_static() } - fn new() -> GridBlock { - GridBlock::new() + fn new() -> BlockMeta { + BlockMeta::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -445,44 +674,44 @@ impl ::protobuf::Message for GridBlock { descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &GridBlock| { &m.id }, - |m: &mut GridBlock| { &mut m.id }, + "block_id", + |m: &BlockMeta| { &m.block_id }, + |m: &mut BlockMeta| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "rows", - |m: &GridBlock| { &m.rows }, - |m: &mut GridBlock| { &mut m.rows }, + |m: &BlockMeta| { &m.rows }, + |m: &mut BlockMeta| { &mut m.rows }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GridBlock", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "BlockMeta", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static GridBlock { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GridBlock::new) + fn default_instance() -> &'static BlockMeta { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(BlockMeta::new) } } -impl ::protobuf::Clear for GridBlock { +impl ::protobuf::Clear for BlockMeta { fn clear(&mut self) { - self.id.clear(); + self.block_id.clear(); self.rows.clear(); self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for GridBlock { +impl ::std::fmt::Debug for BlockMeta { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for GridBlock { +impl ::protobuf::reflect::ProtobufValue for BlockMeta { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -1997,34 +2226,36 @@ impl ::protobuf::reflect::ProtobufValue for FieldType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\nmeta.proto\"a\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \n\nmeta.proto\"c\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ \x06gridId\x12\x1e\n\x06fields\x18\x02\x20\x03(\x0b2\x06.FieldR\x06field\ - s\x12\x1c\n\x04rows\x18\x03\x20\x03(\x0b2\x08.RowMetaR\x04rows\"9\n\tGri\ - dBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x1c\n\x04rows\x18\ - \x02\x20\x03(\x0b2\x08.RowMetaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\ - \x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\ - \x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_typ\ - e\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\ - \x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\ - \nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\x12+\n\ - \x0ctype_options\x18\x08\x20\x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\ - \rRepeatedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05i\ - tems\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\ - \x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xfd\x01\n\x07RowMet\ - a\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\ - \x20\x01(\tR\x06gridId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\ - \x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\ - \x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\ - \nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\ - \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\ - value:\x028\x01\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ - \tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08\ - field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\ - \x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05\ - R\x06height*d\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\x08Checkbox\x10\x05b\x06prot\ - o3\ + s\x12\x1e\n\x06blocks\x18\x03\x20\x03(\x0b2\x06.BlockR\x06blocks\"\\\n\ + \x05Block\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12&\n\x0fstart_row_\ + index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\ + \x20\x01(\x05R\x08rowCount\"D\n\tBlockMeta\x12\x19\n\x08block_id\x18\x01\ + \x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.RowM\ + etaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ + \x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ + \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\ + FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ + n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ + idth\x18\x07\x20\x01(\x05R\x05width\x12+\n\x0ctype_options\x18\x08\x20\ + \x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\rRepeatedField\x12\x1c\n\x05\ + items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"8\n\x07AnyData\x12\x17\ + \n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\ + \x20\x01(\x0cR\x05value\"\xfd\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\ + \x20\x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\ + \x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByFiel\ + dIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06he\ + ight\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\n\x12C\ + ellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\ + \x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\x82\x01\ + \n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06ro\ + w_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\ + \tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\x08.AnyDataR\x04d\ + ata\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06height*d\n\tFieldType\ + \x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08Date\ + Time\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\ + \x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 24149d1fa0..f3757d40ed 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -3,10 +3,15 @@ syntax = "proto3"; message GridMeta { string grid_id = 1; repeated Field fields = 2; - repeated RowMeta rows = 3; + repeated Block blocks = 3; } -message GridBlock { +message Block { string id = 1; + int32 start_row_index = 2; + int32 row_count = 3; +} +message BlockMeta { + string block_id = 1; repeated RowMeta rows = 2; } message Field { diff --git a/shared-lib/flowy-grid-data-model/tests/serde_test.rs b/shared-lib/flowy-grid-data-model/tests/serde_test.rs index 203651a9a0..2d1495e811 100644 --- a/shared-lib/flowy-grid-data-model/tests/serde_test.rs +++ b/shared-lib/flowy-grid-data-model/tests/serde_test.rs @@ -7,14 +7,14 @@ fn grid_serde_test() { let grid = GridMeta { grid_id, fields, - rows: vec![], + blocks: vec![], }; let grid_1_json = serde_json::to_string(&grid).unwrap(); - let _: Grid = serde_json::from_str(&grid_1_json).unwrap(); + let _: GridMeta = serde_json::from_str(&grid_1_json).unwrap(); assert_eq!( grid_1_json, - r#"{"id":"1","fields":[{"id":"1","name":"Text Field","desc":"","field_type":"RichText","frozen":false,"visibility":true,"width":150,"type_options":{"type_id":"","value":[]}}],"rows":[]}"# + r#"{"id":"1","fields":[{"id":"1","name":"Text Field","desc":"","field_type":"RichText","frozen":false,"visibility":true,"width":150,"type_options":{"type_id":"","value":[]}}],"blocks":[]}"# ) } @@ -24,11 +24,11 @@ fn grid_default_serde_test() { let grid = GridMeta { grid_id, fields: vec![], - rows: vec![], + blocks: vec![], }; let json = serde_json::to_string(&grid).unwrap(); - assert_eq!(json, r#"{"id":"1","fields":[],"row_orders":[]}"#) + assert_eq!(json, r#"{"id":"1","fields":[],"blocks":[]}"#) } fn create_field(field_id: &str) -> Field { From cea7d30a53425503dbf7531592d037acc7df8978 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 10 Mar 2022 21:43:23 +0800 Subject: [PATCH 09/28] chore: config BlockMetaPad --- .../flowy-grid-data-model/meta.pb.dart | 109 +++++ .../flowy-grid-data-model/meta.pbjson.dart | 28 ++ frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- .../tests/editor/attribute_test.rs | 10 +- .../flowy-block/tests/editor/serde_test.rs | 6 +- .../src/client_document/default/mod.rs | 2 +- .../src/client_document/document_pad.rs | 2 +- .../src/client_folder/folder_pad.rs | 6 +- .../src/client_grid/block_pad.rs | 181 +++++++-- .../src/entities/meta.rs | 19 +- .../src/protobuf/model/meta.rs | 380 ++++++++++++++++-- .../src/protobuf/proto/meta.proto | 8 +- shared-lib/lib-ot/src/core/delta/delta.rs | 4 +- 13 files changed, 684 insertions(+), 75 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 4ac91c7ff1..8ca629edfa 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -552,6 +552,115 @@ class RowMeta extends $pb.GeneratedMessage { void clearVisibility() => clearField(5); } +enum RowMetaChangeset_OneOfHeight { + height, + notSet +} + +enum RowMetaChangeset_OneOfVisibility { + visibility, + notSet +} + +class RowMetaChangeset extends $pb.GeneratedMessage { + static const $core.Map<$core.int, RowMetaChangeset_OneOfHeight> _RowMetaChangeset_OneOfHeightByTag = { + 2 : RowMetaChangeset_OneOfHeight.height, + 0 : RowMetaChangeset_OneOfHeight.notSet + }; + static const $core.Map<$core.int, RowMetaChangeset_OneOfVisibility> _RowMetaChangeset_OneOfVisibilityByTag = { + 3 : RowMetaChangeset_OneOfVisibility.visibility, + 0 : RowMetaChangeset_OneOfVisibility.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowMetaChangeset', createEmptyInstance: create) + ..oo(0, [2]) + ..oo(1, [3]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) + ..aOB(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') + ..m<$core.String, CellMeta>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'RowMetaChangeset.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: CellMeta.create) + ..hasRequiredFields = false + ; + + RowMetaChangeset._() : super(); + factory RowMetaChangeset({ + $core.String? rowId, + $core.int? height, + $core.bool? visibility, + $core.Map<$core.String, CellMeta>? cellByFieldId, + }) { + final _result = create(); + if (rowId != null) { + _result.rowId = rowId; + } + if (height != null) { + _result.height = height; + } + if (visibility != null) { + _result.visibility = visibility; + } + if (cellByFieldId != null) { + _result.cellByFieldId.addAll(cellByFieldId); + } + return _result; + } + factory RowMetaChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RowMetaChangeset.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RowMetaChangeset clone() => RowMetaChangeset()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RowMetaChangeset copyWith(void Function(RowMetaChangeset) updates) => super.copyWith((message) => updates(message as RowMetaChangeset)) as RowMetaChangeset; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RowMetaChangeset create() => RowMetaChangeset._(); + RowMetaChangeset createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RowMetaChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RowMetaChangeset? _defaultInstance; + + RowMetaChangeset_OneOfHeight whichOneOfHeight() => _RowMetaChangeset_OneOfHeightByTag[$_whichOneof(0)]!; + void clearOneOfHeight() => clearField($_whichOneof(0)); + + RowMetaChangeset_OneOfVisibility whichOneOfVisibility() => _RowMetaChangeset_OneOfVisibilityByTag[$_whichOneof(1)]!; + void clearOneOfVisibility() => clearField($_whichOneof(1)); + + @$pb.TagNumber(1) + $core.String get rowId => $_getSZ(0); + @$pb.TagNumber(1) + set rowId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasRowId() => $_has(0); + @$pb.TagNumber(1) + void clearRowId() => clearField(1); + + @$pb.TagNumber(2) + $core.int get height => $_getIZ(1); + @$pb.TagNumber(2) + set height($core.int v) { $_setSignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasHeight() => $_has(1); + @$pb.TagNumber(2) + void clearHeight() => clearField(2); + + @$pb.TagNumber(3) + $core.bool get visibility => $_getBF(2); + @$pb.TagNumber(3) + set visibility($core.bool v) { $_setBool(2, v); } + @$pb.TagNumber(3) + $core.bool hasVisibility() => $_has(2); + @$pb.TagNumber(3) + void clearVisibility() => clearField(3); + + @$pb.TagNumber(4) + $core.Map<$core.String, CellMeta> get cellByFieldId => $_getMap(3); +} + class CellMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index d0d94fd269..89b7a3c88b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -121,6 +121,34 @@ const RowMeta_CellByFieldIdEntry$json = const { /// Descriptor for `RowMeta`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List rowMetaDescriptor = $convert.base64Decode('CgdSb3dNZXRhEg4KAmlkGAEgASgJUgJpZBIXCgdncmlkX2lkGAIgASgJUgZncmlkSWQSRAoQY2VsbF9ieV9maWVsZF9pZBgDIAMoCzIbLlJvd01ldGEuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgEIAEoBVIGaGVpZ2h0Eh4KCnZpc2liaWxpdHkYBSABKAhSCnZpc2liaWxpdHkaSwoSQ2VsbEJ5RmllbGRJZEVudHJ5EhAKA2tleRgBIAEoCVIDa2V5Eh8KBXZhbHVlGAIgASgLMgkuQ2VsbE1ldGFSBXZhbHVlOgI4AQ=='); +@$core.Deprecated('Use rowMetaChangesetDescriptor instead') +const RowMetaChangeset$json = const { + '1': 'RowMetaChangeset', + '2': const [ + const {'1': 'row_id', '3': 1, '4': 1, '5': 9, '10': 'rowId'}, + const {'1': 'height', '3': 2, '4': 1, '5': 5, '9': 0, '10': 'height'}, + const {'1': 'visibility', '3': 3, '4': 1, '5': 8, '9': 1, '10': 'visibility'}, + const {'1': 'cell_by_field_id', '3': 4, '4': 3, '5': 11, '6': '.RowMetaChangeset.CellByFieldIdEntry', '10': 'cellByFieldId'}, + ], + '3': const [RowMetaChangeset_CellByFieldIdEntry$json], + '8': const [ + const {'1': 'one_of_height'}, + const {'1': 'one_of_visibility'}, + ], +}; + +@$core.Deprecated('Use rowMetaChangesetDescriptor instead') +const RowMetaChangeset_CellByFieldIdEntry$json = const { + '1': 'CellByFieldIdEntry', + '2': const [ + const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'}, + const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.CellMeta', '10': 'value'}, + ], + '7': const {'7': true}, +}; + +/// Descriptor for `RowMetaChangeset`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List rowMetaChangesetDescriptor = $convert.base64Decode('ChBSb3dNZXRhQ2hhbmdlc2V0EhUKBnJvd19pZBgBIAEoCVIFcm93SWQSGAoGaGVpZ2h0GAIgASgFSABSBmhlaWdodBIgCgp2aXNpYmlsaXR5GAMgASgISAFSCnZpc2liaWxpdHkSTQoQY2VsbF9ieV9maWVsZF9pZBgEIAMoCzIkLlJvd01ldGFDaGFuZ2VzZXQuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkGksKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIfCgV2YWx1ZRgCIAEoCzIJLkNlbGxNZXRhUgV2YWx1ZToCOAFCDwoNb25lX29mX2hlaWdodEITChFvbmVfb2ZfdmlzaWJpbGl0eQ=='); @$core.Deprecated('Use cellMetaDescriptor instead') const CellMeta$json = const { '1': 'CellMeta', diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 96755db623..046fd85668 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [lib] name = "dart_ffi" # this value will change depending on the target os -# default staticlib -crate-type = ["staticlib"] +# default cdylib +crate-type = ["cdylib"] [dependencies] diff --git a/frontend/rust-lib/flowy-block/tests/editor/attribute_test.rs b/frontend/rust-lib/flowy-block/tests/editor/attribute_test.rs index fb91e8125c..264cee831b 100644 --- a/frontend/rust-lib/flowy-block/tests/editor/attribute_test.rs +++ b/frontend/rust-lib/flowy-block/tests/editor/attribute_test.rs @@ -762,12 +762,12 @@ fn attributes_preserve_list_format_on_merge() { #[test] fn delta_compose() { - let mut delta = RichTextDelta::from_json(r#"[{"insert":"\n"}]"#).unwrap(); + let mut delta = RichTextDelta::from_delta_str(r#"[{"insert":"\n"}]"#).unwrap(); let deltas = vec![ - RichTextDelta::from_json(r#"[{"retain":1,"attributes":{"list":"unchecked"}}]"#).unwrap(), - RichTextDelta::from_json(r#"[{"insert":"a"}]"#).unwrap(), - RichTextDelta::from_json(r#"[{"retain":1},{"insert":"\n","attributes":{"list":"unchecked"}}]"#).unwrap(), - RichTextDelta::from_json(r#"[{"retain":2},{"retain":1,"attributes":{"list":""}}]"#).unwrap(), + RichTextDelta::from_delta_str(r#"[{"retain":1,"attributes":{"list":"unchecked"}}]"#).unwrap(), + RichTextDelta::from_delta_str(r#"[{"insert":"a"}]"#).unwrap(), + RichTextDelta::from_delta_str(r#"[{"retain":1},{"insert":"\n","attributes":{"list":"unchecked"}}]"#).unwrap(), + RichTextDelta::from_delta_str(r#"[{"retain":2},{"retain":1,"attributes":{"list":""}}]"#).unwrap(), ]; for d in deltas { diff --git a/frontend/rust-lib/flowy-block/tests/editor/serde_test.rs b/frontend/rust-lib/flowy-block/tests/editor/serde_test.rs index 71c5e64dc3..54c7f92152 100644 --- a/frontend/rust-lib/flowy-block/tests/editor/serde_test.rs +++ b/frontend/rust-lib/flowy-block/tests/editor/serde_test.rs @@ -65,7 +65,7 @@ fn delta_serialize_multi_attribute_test() { let json = serde_json::to_string(&delta).unwrap(); eprintln!("{}", json); - let delta_from_json = Delta::from_json(&json).unwrap(); + let delta_from_json = Delta::from_delta_str(&json).unwrap(); assert_eq!(delta_from_json, delta); } @@ -77,7 +77,7 @@ fn delta_deserialize_test() { {"retain":2,"attributes":{"italic":"true","bold":"true"}}, {"retain":2,"attributes":{"italic":true,"bold":true}} ]"#; - let delta = RichTextDelta::from_json(json).unwrap(); + let delta = RichTextDelta::from_delta_str(json).unwrap(); eprintln!("{}", delta); } @@ -86,7 +86,7 @@ fn delta_deserialize_null_test() { let json = r#"[ {"retain":7,"attributes":{"bold":null}} ]"#; - let delta1 = RichTextDelta::from_json(json).unwrap(); + let delta1 = RichTextDelta::from_delta_str(json).unwrap(); let mut attribute = RichTextAttribute::Bold(true); attribute.value = RichTextAttributeValue(None); diff --git a/shared-lib/flowy-collaboration/src/client_document/default/mod.rs b/shared-lib/flowy-collaboration/src/client_document/default/mod.rs index be6b679c81..f5fb180571 100644 --- a/shared-lib/flowy-collaboration/src/client_document/default/mod.rs +++ b/shared-lib/flowy-collaboration/src/client_document/default/mod.rs @@ -13,7 +13,7 @@ pub fn initial_quill_delta_string() -> String { #[inline] pub fn initial_read_me() -> RichTextDelta { let json = include_str!("READ_ME.json"); - RichTextDelta::from_json(json).unwrap() + RichTextDelta::from_delta_str(json).unwrap() } #[cfg(test)] diff --git a/shared-lib/flowy-collaboration/src/client_document/document_pad.rs b/shared-lib/flowy-collaboration/src/client_document/document_pad.rs index 0a537a8c8d..4807d9869c 100644 --- a/shared-lib/flowy-collaboration/src/client_document/document_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_document/document_pad.rs @@ -54,7 +54,7 @@ impl ClientDocument { } pub fn from_json(json: &str) -> Result { - let delta = RichTextDelta::from_json(json)?; + let delta = RichTextDelta::from_delta_str(json)?; Ok(Self::from_delta(delta)) } diff --git a/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs b/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs index 455f12c002..4fd8a1982e 100644 --- a/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs @@ -307,7 +307,7 @@ impl FolderPad { if let Some(workspace) = workspaces.iter_mut().find(|workspace| workspace_id == workspace.id) { f(Arc::make_mut(workspace)) } else { - tracing::warn!("[RootFolder]: Can't find any workspace with id: {}", workspace_id); + tracing::warn!("[FolderPad]: Can't find any workspace with id: {}", workspace_id); Ok(None) } }) @@ -344,7 +344,7 @@ impl FolderPad { .find(|workspace| workspace.apps.iter().any(|app| app.id == app_id)) { None => { - tracing::warn!("[RootFolder]: Can't find any app with id: {}", app_id); + tracing::warn!("[FolderPad]: Can't find any app with id: {}", app_id); return Ok(None); } Some(workspace) => workspace.id.clone(), @@ -363,7 +363,7 @@ impl FolderPad { self.with_app(belong_to_id, |app| { match app.belongings.iter_mut().find(|view| view_id == view.id) { None => { - tracing::warn!("[RootFolder]: Can't find any view with id: {}", view_id); + tracing::warn!("[FolderPad]: Can't find any view with id: {}", view_id); Ok(None) } Some(view) => f(view), diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index 23f07e3efb..54f4b67967 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -1,30 +1,33 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{BlockMeta, RowMeta, RowOrder}; +use flowy_grid_data_model::entities::{BlockMeta, RowMeta, RowMetaChangeset, RowOrder}; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; +use serde::{Deserialize, Serialize}; use std::sync::Arc; pub type BlockMetaDelta = PlainTextDelta; pub type BlockDeltaBuilder = PlainTextDeltaBuilder; +#[derive(Debug, Deserialize, Serialize, Clone)] pub struct BlockMetaPad { - pub(crate) block_meta: Arc, + block_id: String, + rows: Vec>, + + #[serde(skip)] pub(crate) delta: BlockMetaDelta, } impl BlockMetaPad { pub fn from_delta(delta: BlockMetaDelta) -> CollaborateResult { let s = delta.to_str()?; - let block_delta: BlockMeta = serde_json::from_str(&s).map_err(|e| { + let block_meta: BlockMeta = serde_json::from_str(&s).map_err(|e| { CollaborateError::internal().context(format!("Deserialize delta to block meta failed: {}", e)) })?; - - Ok(Self { - block_meta: Arc::new(block_delta), - delta, - }) + let block_id = block_meta.block_id; + let rows = block_meta.rows.into_iter().map(Arc::new).collect::>>(); + Ok(Self { block_id, rows, delta }) } pub fn from_revisions(_grid_id: &str, revisions: Vec) -> CollaborateResult { @@ -32,38 +35,55 @@ impl BlockMetaPad { Self::from_delta(block_delta) } - pub fn create_row(&mut self, row: RowMeta) -> CollaborateResult> { - self.modify(|grid| { - grid.rows.push(row); + pub fn add_row(&mut self, row: RowMeta) -> CollaborateResult> { + self.modify(|rows| { + rows.push(Arc::new(row)); Ok(Some(())) }) } pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { - self.modify(|grid| { - grid.rows.retain(|row| !row_ids.contains(&row.id)); + self.modify(|rows| { + rows.retain(|row| !row_ids.contains(&row.id)); Ok(Some(())) }) } - pub fn md5(&self) -> String { - md5(&self.delta.to_bytes()) - } + pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { + let row_id = changeset.row_id.clone(); + self.modify_row(&row_id, |row| { + let mut is_changed = None; + if let Some(height) = changeset.height { + row.height = height; + is_changed = Some(()); + } - pub fn delta_str(&self) -> String { - self.delta.to_delta_str() + if let Some(visibility) = changeset.visibility { + row.visibility = visibility; + is_changed = Some(()); + } + + if !changeset.cell_by_field_id.is_empty() { + is_changed = Some(()); + changeset.cell_by_field_id.into_iter().for_each(|(field_id, cell)| { + row.cell_by_field_id.insert(field_id, cell); + }) + } + + Ok(is_changed) + }) } pub fn modify(&mut self, f: F) -> CollaborateResult> where - F: FnOnce(&mut BlockMeta) -> CollaborateResult>, + F: for<'a> FnOnce(&'a mut Vec>) -> CollaborateResult>, { - let cloned_meta = self.block_meta.clone(); - match f(Arc::make_mut(&mut self.block_meta))? { + let cloned_self = self.clone(); + match f(&mut self.rows)? { None => Ok(None), Some(_) => { - let old = json_from_grid(&cloned_meta)?; - let new = json_from_grid(&self.block_meta)?; + let old = cloned_self.to_json()?; + let new = self.to_json()?; match cal_diff::(old, new) { None => Ok(None), Some(delta) => { @@ -74,6 +94,33 @@ impl BlockMetaPad { } } } + + fn modify_row(&mut self, row_id: &str, f: F) -> CollaborateResult> + where + F: FnOnce(&mut RowMeta) -> CollaborateResult>, + { + self.modify(|rows| { + if let Some(row_meta) = rows.iter_mut().find(|row_meta| row_id == row_meta.id) { + f(Arc::make_mut(row_meta)) + } else { + tracing::warn!("[BlockMetaPad]: Can't find any row with id: {}", row_id); + Ok(None) + } + }) + } + + pub fn to_json(&self) -> CollaborateResult { + serde_json::to_string(self) + .map_err(|e| CollaborateError::internal().context(format!("serial trash to json failed: {}", e))) + } + + pub fn md5(&self) -> String { + md5(&self.delta.to_bytes()) + } + + pub fn delta_str(&self) -> String { + self.delta.to_delta_str() + } } fn json_from_grid(block_meta: &Arc) -> CollaborateResult { @@ -106,10 +153,96 @@ impl std::default::Default for BlockMetaPad { block_id: uuid(), rows: vec![], }; + let delta = make_block_meta_delta(&block_meta); BlockMetaPad { - block_meta: Arc::new(block_meta), + block_id: block_meta.block_id, + rows: block_meta.rows.into_iter().map(Arc::new).collect::>(), delta, } } } + +#[cfg(test)] +mod tests { + use crate::client_grid::{BlockMetaDelta, BlockMetaPad}; + use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset}; + use std::str::FromStr; + + #[test] + fn block_meta_add_row() { + let mut pad = test_pad(); + let row = RowMeta { + id: "1".to_string(), + block_id: pad.block_id.clone(), + cell_by_field_id: Default::default(), + height: 0, + visibility: false, + }; + + let change = pad.add_row(row).unwrap().unwrap(); + assert_eq!( + change.delta.to_delta_str(), + r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + ); + } + + #[test] + fn block_meta_delete_row() { + let mut pad = test_pad(); + let pre_delta_str = pad.delta_str(); + let row = RowMeta { + id: "1".to_string(), + block_id: pad.block_id.clone(), + cell_by_field_id: Default::default(), + height: 0, + visibility: false, + }; + + let _ = pad.add_row(row.clone()).unwrap().unwrap(); + let change = pad.delete_rows(&[row.id]).unwrap().unwrap(); + assert_eq!( + change.delta.to_delta_str(), + r#"[{"retain":24},{"delete":77},{"retain":2}]"# + ); + + assert_eq!(pad.delta_str(), pre_delta_str); + } + + #[test] + fn block_meta_update_row() { + let mut pad = test_pad(); + let row = RowMeta { + id: "1".to_string(), + block_id: pad.block_id.clone(), + cell_by_field_id: Default::default(), + height: 0, + visibility: false, + }; + + let changeset = RowMetaChangeset { + row_id: row.id.clone(), + height: Some(100), + visibility: Some(true), + cell_by_field_id: Default::default(), + }; + + let _ = pad.add_row(row.clone()).unwrap().unwrap(); + let change = pad.update_row(changeset).unwrap().unwrap(); + + assert_eq!( + change.delta.to_delta_str(), + r#"[{"retain":80},{"insert":"10"},{"retain":15},{"insert":"tru"},{"delete":4},{"retain":4}]"# + ); + + assert_eq!( + pad.to_json().unwrap(), + r#"{"block_id":"1","rows":[{"id":"1","block_id":"1","cell_by_field_id":{},"height":100,"visibility":true}]}"# + ); + } + + fn test_pad() -> BlockMetaPad { + let delta = BlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap(); + BlockMetaPad::from_delta(delta).unwrap() + } +} diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 5fbd55ffa6..e8483dcb02 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -178,7 +178,7 @@ pub struct RowMeta { pub id: String, #[pb(index = 2)] - pub grid_id: String, + pub block_id: String, #[pb(index = 3)] pub cell_by_field_id: HashMap, @@ -199,7 +199,7 @@ impl RowMeta { Self { id: id.to_owned(), - grid_id: grid_id.to_owned(), + block_id: grid_id.to_owned(), cell_by_field_id, height: DEFAULT_ROW_HEIGHT, visibility: true, @@ -207,6 +207,21 @@ impl RowMeta { } } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct RowMetaChangeset { + #[pb(index = 1)] + pub row_id: String, + + #[pb(index = 2, one_of)] + pub height: Option, + + #[pb(index = 3, one_of)] + pub visibility: Option, + + #[pb(index = 4)] + pub cell_by_field_id: HashMap, +} + #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] pub struct CellMeta { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index a542d09d7d..4107603b67 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -1524,7 +1524,7 @@ impl ::protobuf::reflect::ProtobufValue for AnyData { pub struct RowMeta { // message fields pub id: ::std::string::String, - pub grid_id: ::std::string::String, + pub block_id: ::std::string::String, pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, CellMeta>, pub height: i32, pub visibility: bool, @@ -1570,30 +1570,30 @@ impl RowMeta { ::std::mem::replace(&mut self.id, ::std::string::String::new()) } - // string grid_id = 2; + // string block_id = 2; - pub fn get_grid_id(&self) -> &str { - &self.grid_id + pub fn get_block_id(&self) -> &str { + &self.block_id } - pub fn clear_grid_id(&mut self) { - self.grid_id.clear(); + pub fn clear_block_id(&mut self) { + self.block_id.clear(); } // Param is passed by value, moved - pub fn set_grid_id(&mut self, v: ::std::string::String) { - self.grid_id = v; + pub fn set_block_id(&mut self, v: ::std::string::String) { + self.block_id = v; } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { - &mut self.grid_id + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id } // Take field - pub fn take_grid_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + pub fn take_block_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) } // repeated .RowMeta.CellByFieldIdEntry cell_by_field_id = 3; @@ -1665,7 +1665,7 @@ impl ::protobuf::Message for RowMeta { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; }, 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, 3 => { ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; @@ -1699,8 +1699,8 @@ impl ::protobuf::Message for RowMeta { if !self.id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.id); } - if !self.grid_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.grid_id); + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.block_id); } my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id); if self.height != 0 { @@ -1718,8 +1718,8 @@ impl ::protobuf::Message for RowMeta { if !self.id.is_empty() { os.write_string(1, &self.id)?; } - if !self.grid_id.is_empty() { - os.write_string(2, &self.grid_id)?; + if !self.block_id.is_empty() { + os.write_string(2, &self.block_id)?; } ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id, os)?; if self.height != 0 { @@ -1772,9 +1772,9 @@ impl ::protobuf::Message for RowMeta { |m: &mut RowMeta| { &mut m.id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "grid_id", - |m: &RowMeta| { &m.grid_id }, - |m: &mut RowMeta| { &mut m.grid_id }, + "block_id", + |m: &RowMeta| { &m.block_id }, + |m: &mut RowMeta| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( "cell_by_field_id", @@ -1808,7 +1808,7 @@ impl ::protobuf::Message for RowMeta { impl ::protobuf::Clear for RowMeta { fn clear(&mut self) { self.id.clear(); - self.grid_id.clear(); + self.block_id.clear(); self.cell_by_field_id.clear(); self.height = 0; self.visibility = false; @@ -1828,6 +1828,317 @@ impl ::protobuf::reflect::ProtobufValue for RowMeta { } } +#[derive(PartialEq,Clone,Default)] +pub struct RowMetaChangeset { + // message fields + pub row_id: ::std::string::String, + pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, CellMeta>, + // message oneof groups + pub one_of_height: ::std::option::Option, + pub one_of_visibility: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RowMetaChangeset { + fn default() -> &'a RowMetaChangeset { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum RowMetaChangeset_oneof_one_of_height { + height(i32), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum RowMetaChangeset_oneof_one_of_visibility { + visibility(bool), +} + +impl RowMetaChangeset { + pub fn new() -> RowMetaChangeset { + ::std::default::Default::default() + } + + // string row_id = 1; + + + pub fn get_row_id(&self) -> &str { + &self.row_id + } + pub fn clear_row_id(&mut self) { + self.row_id.clear(); + } + + // Param is passed by value, moved + pub fn set_row_id(&mut self, v: ::std::string::String) { + self.row_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_id(&mut self) -> &mut ::std::string::String { + &mut self.row_id + } + + // Take field + pub fn take_row_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) + } + + // int32 height = 2; + + + pub fn get_height(&self) -> i32 { + match self.one_of_height { + ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_height::height(v)) => v, + _ => 0, + } + } + pub fn clear_height(&mut self) { + self.one_of_height = ::std::option::Option::None; + } + + pub fn has_height(&self) -> bool { + match self.one_of_height { + ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_height::height(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: i32) { + self.one_of_height = ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_height::height(v)) + } + + // bool visibility = 3; + + + pub fn get_visibility(&self) -> bool { + match self.one_of_visibility { + ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_visibility::visibility(v)) => v, + _ => false, + } + } + pub fn clear_visibility(&mut self) { + self.one_of_visibility = ::std::option::Option::None; + } + + pub fn has_visibility(&self) -> bool { + match self.one_of_visibility { + ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_visibility::visibility(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_visibility(&mut self, v: bool) { + self.one_of_visibility = ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_visibility::visibility(v)) + } + + // repeated .RowMetaChangeset.CellByFieldIdEntry cell_by_field_id = 4; + + + pub fn get_cell_by_field_id(&self) -> &::std::collections::HashMap<::std::string::String, CellMeta> { + &self.cell_by_field_id + } + pub fn clear_cell_by_field_id(&mut self) { + self.cell_by_field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_cell_by_field_id(&mut self, v: ::std::collections::HashMap<::std::string::String, CellMeta>) { + self.cell_by_field_id = v; + } + + // Mutable pointer to the field. + pub fn mut_cell_by_field_id(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, CellMeta> { + &mut self.cell_by_field_id + } + + // Take field + pub fn take_cell_by_field_id(&mut self) -> ::std::collections::HashMap<::std::string::String, CellMeta> { + ::std::mem::replace(&mut self.cell_by_field_id, ::std::collections::HashMap::new()) + } +} + +impl ::protobuf::Message for RowMetaChangeset { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_height = ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_height::height(is.read_int32()?)); + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_visibility = ::std::option::Option::Some(RowMetaChangeset_oneof_one_of_visibility::visibility(is.read_bool()?)); + }, + 4 => { + ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.row_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.row_id); + } + my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(4, &self.cell_by_field_id); + if let ::std::option::Option::Some(ref v) = self.one_of_height { + match v { + &RowMetaChangeset_oneof_one_of_height::height(v) => { + my_size += ::protobuf::rt::value_size(2, v, ::protobuf::wire_format::WireTypeVarint); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_visibility { + match v { + &RowMetaChangeset_oneof_one_of_visibility::visibility(v) => { + my_size += 2; + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.row_id.is_empty() { + os.write_string(1, &self.row_id)?; + } + ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(4, &self.cell_by_field_id, os)?; + if let ::std::option::Option::Some(ref v) = self.one_of_height { + match v { + &RowMetaChangeset_oneof_one_of_height::height(v) => { + os.write_int32(2, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_visibility { + match v { + &RowMetaChangeset_oneof_one_of_visibility::visibility(v) => { + os.write_bool(3, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RowMetaChangeset { + RowMetaChangeset::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &RowMetaChangeset| { &m.row_id }, + |m: &mut RowMetaChangeset| { &mut m.row_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_i32_accessor::<_>( + "height", + RowMetaChangeset::has_height, + RowMetaChangeset::get_height, + )); + fields.push(::protobuf::reflect::accessor::make_singular_bool_accessor::<_>( + "visibility", + RowMetaChangeset::has_visibility, + RowMetaChangeset::get_visibility, + )); + fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( + "cell_by_field_id", + |m: &RowMetaChangeset| { &m.cell_by_field_id }, + |m: &mut RowMetaChangeset| { &mut m.cell_by_field_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RowMetaChangeset", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RowMetaChangeset { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RowMetaChangeset::new) + } +} + +impl ::protobuf::Clear for RowMetaChangeset { + fn clear(&mut self) { + self.row_id.clear(); + self.one_of_height = ::std::option::Option::None; + self.one_of_visibility = ::std::option::Option::None; + self.cell_by_field_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RowMetaChangeset { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RowMetaChangeset { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct CellMeta { // message fields @@ -2242,20 +2553,27 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\rRepeatedField\x12\x1c\n\x05\ items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"8\n\x07AnyData\x12\x17\ \n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\ - \x20\x01(\x0cR\x05value\"\xfd\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\ - \x20\x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\ + \x20\x01(\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\ + \x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\ \x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByFiel\ dIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06he\ ight\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\n\x12C\ ellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\ - \x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\x82\x01\ - \n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06ro\ - w_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\ - \tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\x08.AnyDataR\x04d\ - ata\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06height*d\n\tFieldType\ - \x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08Date\ - Time\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\ - \x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ + \x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\xa7\x02\ + \n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ + \x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\n\nvisib\ + ility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_field_id\ + \x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rcellByFiel\ + dId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\ + \x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\ + \x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"\x82\x01\n\ + \x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06row_\ + id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\t\ + R\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\x08.AnyDataR\x04dat\ + a\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06height*d\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\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index f3757d40ed..dc00b1e72c 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -33,11 +33,17 @@ message AnyData { } message RowMeta { string id = 1; - string grid_id = 2; + string block_id = 2; map cell_by_field_id = 3; int32 height = 4; bool visibility = 5; } +message RowMetaChangeset { + string row_id = 1; + oneof one_of_height { int32 height = 2; }; + oneof one_of_visibility { bool visibility = 3; }; + map cell_by_field_id = 4; +} message CellMeta { string id = 1; string row_id = 2; diff --git a/shared-lib/lib-ot/src/core/delta/delta.rs b/shared-lib/lib-ot/src/core/delta/delta.rs index e9a7e15e12..ac4fcbbef5 100644 --- a/shared-lib/lib-ot/src/core/delta/delta.rs +++ b/shared-lib/lib-ot/src/core/delta/delta.rs @@ -501,7 +501,7 @@ impl Delta where T: Attributes + DeserializeOwned, { - pub fn from_json(json: &str) -> Result { + pub fn from_delta_str(json: &str) -> Result { let delta = serde_json::from_str(json).map_err(|e| { tracing::trace!("Deserialize failed: {:?}", e); tracing::trace!("{:?}", json); @@ -512,7 +512,7 @@ where pub fn from_bytes>(bytes: B) -> Result { let json = str::from_utf8(bytes.as_ref())?.to_owned(); - let val = Self::from_json(&json)?; + let val = Self::from_delta_str(&json)?; Ok(val) } } From 9a791974b44bf866348e85414850100f3bd0e8fa Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 10 Mar 2022 22:27:19 +0800 Subject: [PATCH 10/28] chore: config grid rev persistence --- .../flowy-collaboration/revision.pbenum.dart | 15 - .../flowy-collaboration/revision.pbjson.dart | 11 - .../flowy-grid-data-model/meta.pb.dart | 16 +- .../flowy-grid-data-model/meta.pbjson.dart | 4 +- frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- .../rust-lib/flowy-database/src/schema.rs | 12 + .../src/services/persistence/mod.rs | 17 +- .../src/cache/disk/grid_rev_impl.rs | 272 ++++++++++++++++++ .../rust-lib/flowy-sync/src/cache/disk/mod.rs | 47 ++- ...ext_block_rev_impl.rs => text_rev_impl.rs} | 102 +++---- .../rust-lib/flowy-sync/src/cache/memory.rs | 3 +- frontend/rust-lib/flowy-sync/src/cache/mod.rs | 2 +- .../rust-lib/flowy-sync/src/rev_manager.rs | 3 +- .../flowy-sync/src/rev_persistence.rs | 24 +- .../src/entities/revision.rs | 21 -- .../src/protobuf/model/revision.rs | 53 +--- .../src/protobuf/proto/revision.proto | 4 - 17 files changed, 404 insertions(+), 206 deletions(-) rename frontend/rust-lib/flowy-sync/src/cache/disk/{text_block_rev_impl.rs => text_rev_impl.rs} (72%) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbenum.dart index 4c2ae91cea..f3c7efb417 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbenum.dart @@ -9,21 +9,6 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; -class RevisionState extends $pb.ProtobufEnum { - static const RevisionState Sync = RevisionState._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Sync'); - static const RevisionState Ack = RevisionState._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Ack'); - - static const $core.List values = [ - Sync, - Ack, - ]; - - static final $core.Map<$core.int, RevisionState> _byValue = $pb.ProtobufEnum.initByValue(values); - static RevisionState? valueOf($core.int value) => _byValue[value]; - - const RevisionState._($core.int v, $core.String n) : super(v, n); -} - class RevType extends $pb.ProtobufEnum { static const RevType DeprecatedLocal = RevType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeprecatedLocal'); static const RevType DeprecatedRemote = RevType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeprecatedRemote'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbjson.dart index 64a4feed7e..5d4db67b74 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbjson.dart @@ -8,17 +8,6 @@ import 'dart:core' as $core; import 'dart:convert' as $convert; import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use revisionStateDescriptor instead') -const RevisionState$json = const { - '1': 'RevisionState', - '2': const [ - const {'1': 'Sync', '2': 0}, - const {'1': 'Ack', '2': 1}, - ], -}; - -/// Descriptor for `RevisionState`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List revisionStateDescriptor = $convert.base64Decode('Cg1SZXZpc2lvblN0YXRlEggKBFN5bmMQABIHCgNBY2sQAQ=='); @$core.Deprecated('Use revTypeDescriptor instead') const RevType$json = const { '1': 'RevType', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 8ca629edfa..924cb4addb 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -458,7 +458,7 @@ class AnyData extends $pb.GeneratedMessage { class RowMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') ..m<$core.String, CellMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'RowMeta.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: CellMeta.create) ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') @@ -468,7 +468,7 @@ class RowMeta extends $pb.GeneratedMessage { RowMeta._() : super(); factory RowMeta({ $core.String? id, - $core.String? gridId, + $core.String? blockId, $core.Map<$core.String, CellMeta>? cellByFieldId, $core.int? height, $core.bool? visibility, @@ -477,8 +477,8 @@ class RowMeta extends $pb.GeneratedMessage { if (id != null) { _result.id = id; } - if (gridId != null) { - _result.gridId = gridId; + if (blockId != null) { + _result.blockId = blockId; } if (cellByFieldId != null) { _result.cellByFieldId.addAll(cellByFieldId); @@ -522,13 +522,13 @@ class RowMeta extends $pb.GeneratedMessage { void clearId() => clearField(1); @$pb.TagNumber(2) - $core.String get gridId => $_getSZ(1); + $core.String get blockId => $_getSZ(1); @$pb.TagNumber(2) - set gridId($core.String v) { $_setString(1, v); } + set blockId($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasGridId() => $_has(1); + $core.bool hasBlockId() => $_has(1); @$pb.TagNumber(2) - void clearGridId() => clearField(2); + void clearBlockId() => clearField(2); @$pb.TagNumber(3) $core.Map<$core.String, CellMeta> get cellByFieldId => $_getMap(2); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 89b7a3c88b..5685a4c17b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -101,7 +101,7 @@ const RowMeta$json = const { '1': 'RowMeta', '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'block_id', '3': 2, '4': 1, '5': 9, '10': 'blockId'}, const {'1': 'cell_by_field_id', '3': 3, '4': 3, '5': 11, '6': '.RowMeta.CellByFieldIdEntry', '10': 'cellByFieldId'}, const {'1': 'height', '3': 4, '4': 1, '5': 5, '10': 'height'}, const {'1': 'visibility', '3': 5, '4': 1, '5': 8, '10': 'visibility'}, @@ -120,7 +120,7 @@ const RowMeta_CellByFieldIdEntry$json = const { }; /// Descriptor for `RowMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rowMetaDescriptor = $convert.base64Decode('CgdSb3dNZXRhEg4KAmlkGAEgASgJUgJpZBIXCgdncmlkX2lkGAIgASgJUgZncmlkSWQSRAoQY2VsbF9ieV9maWVsZF9pZBgDIAMoCzIbLlJvd01ldGEuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgEIAEoBVIGaGVpZ2h0Eh4KCnZpc2liaWxpdHkYBSABKAhSCnZpc2liaWxpdHkaSwoSQ2VsbEJ5RmllbGRJZEVudHJ5EhAKA2tleRgBIAEoCVIDa2V5Eh8KBXZhbHVlGAIgASgLMgkuQ2VsbE1ldGFSBXZhbHVlOgI4AQ=='); +final $typed_data.Uint8List rowMetaDescriptor = $convert.base64Decode('CgdSb3dNZXRhEg4KAmlkGAEgASgJUgJpZBIZCghibG9ja19pZBgCIAEoCVIHYmxvY2tJZBJEChBjZWxsX2J5X2ZpZWxkX2lkGAMgAygLMhsuUm93TWV0YS5DZWxsQnlGaWVsZElkRW50cnlSDWNlbGxCeUZpZWxkSWQSFgoGaGVpZ2h0GAQgASgFUgZoZWlnaHQSHgoKdmlzaWJpbGl0eRgFIAEoCFIKdmlzaWJpbGl0eRpLChJDZWxsQnlGaWVsZElkRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSHwoFdmFsdWUYAiABKAsyCS5DZWxsTWV0YVIFdmFsdWU6AjgB'); @$core.Deprecated('Use rowMetaChangesetDescriptor instead') const RowMetaChangeset$json = const { '1': 'RowMetaChangeset', diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 046fd85668..96755db623 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [lib] name = "dart_ffi" # this value will change depending on the target os -# default cdylib -crate-type = ["cdylib"] +# default staticlib +crate-type = ["staticlib"] [dependencies] diff --git a/frontend/rust-lib/flowy-database/src/schema.rs b/frontend/rust-lib/flowy-database/src/schema.rs index aa7200000e..7397f5b704 100644 --- a/frontend/rust-lib/flowy-database/src/schema.rs +++ b/frontend/rust-lib/flowy-database/src/schema.rs @@ -21,6 +21,17 @@ table! { } } +table! { + grid_rev_table (id) { + id -> Integer, + object_id -> Text, + base_rev_id -> BigInt, + rev_id -> BigInt, + data -> Binary, + state -> Integer, + } +} + table! { kv_table (key) { key -> Text, @@ -91,6 +102,7 @@ table! { allow_tables_to_appear_in_same_query!( app_table, doc_table, + grid_rev_table, kv_table, rev_table, trash_table, 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 fa473ea063..b05490b70a 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs @@ -2,20 +2,13 @@ mod migration; pub mod version_1; mod version_2; -use flowy_collaboration::client_folder::initial_folder_delta; -use flowy_collaboration::{ - client_folder::FolderPad, - entities::revision::{Revision, RevisionState}, -}; -use std::sync::Arc; -use tokio::sync::RwLock; -pub use version_1::{app_sql::*, trash_sql::*, v1_impl::V1Transaction, view_sql::*, workspace_sql::*}; - use crate::{ event_map::WorkspaceDatabase, manager::FolderId, services::{folder_editor::ClientFolderEditor, persistence::migration::FolderMigration}, }; +use flowy_collaboration::client_folder::initial_folder_delta; +use flowy_collaboration::{client_folder::FolderPad, entities::revision::Revision}; use flowy_error::{FlowyError, FlowyResult}; use flowy_folder_data_model::entities::{ app::App, @@ -23,8 +16,12 @@ use flowy_folder_data_model::entities::{ view::View, workspace::Workspace, }; -use flowy_sync::{mk_revision_disk_cache, RevisionRecord}; +use flowy_sync::disk::{RevisionRecord, RevisionState}; +use flowy_sync::mk_revision_disk_cache; use lib_sqlite::ConnectionPool; +use std::sync::Arc; +use tokio::sync::RwLock; +pub use version_1::{app_sql::*, trash_sql::*, v1_impl::V1Transaction, view_sql::*, workspace_sql::*}; pub trait FolderPersistenceTransaction { fn create_workspace(&self, user_id: &str, workspace: Workspace) -> FlowyResult<()>; diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs index e69de29bb2..6053b17133 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs @@ -0,0 +1,272 @@ +use crate::cache::disk::RevisionDiskCache; +use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; +use bytes::Bytes; +use diesel::{sql_types::Integer, update, SqliteConnection}; +use flowy_collaboration::{ + entities::revision::{RevId, RevType, Revision, RevisionRange}, + util::md5, +}; +use flowy_database::{ + impl_sql_integer_expression, insert_or_ignore_into, + prelude::*, + schema::{grid_rev_table, grid_rev_table::dsl}, + ConnectionPool, +}; +use flowy_error::{internal_error, FlowyError, FlowyResult}; +use std::sync::Arc; + +pub struct SQLiteGridRevisionPersistence { + user_id: String, + pub(crate) pool: Arc, +} + +impl RevisionDiskCache for SQLiteGridRevisionPersistence { + type Error = FlowyError; + + fn create_revision_records( + &self, + revision_records: Vec, + conn: &SqliteConnection, + ) -> Result<(), Self::Error> { + let _ = GridRevisionSql::create(revision_records, conn)?; + Ok(()) + } + + fn read_revision_records( + &self, + object_id: &str, + rev_ids: Option>, + ) -> Result, Self::Error> { + let conn = self.pool.get().map_err(internal_error)?; + let records = GridRevisionSql::read(&self.user_id, object_id, rev_ids, &*conn)?; + Ok(records) + } + + fn read_revision_records_with_range( + &self, + object_id: &str, + range: &RevisionRange, + ) -> Result, Self::Error> { + let conn = &*self.pool.get().map_err(internal_error)?; + let revisions = GridRevisionSql::read_with_range(&self.user_id, object_id, range.clone(), conn)?; + Ok(revisions) + } + + fn update_revision_record(&self, changesets: Vec) -> FlowyResult<()> { + let conn = &*self.pool.get().map_err(internal_error)?; + let _ = conn.immediate_transaction::<_, FlowyError, _>(|| { + for changeset in changesets { + let _ = GridRevisionSql::update(changeset, conn)?; + } + Ok(()) + })?; + Ok(()) + } + + fn delete_revision_records(&self, object_id: &str, rev_ids: Option>) -> Result<(), Self::Error> { + let conn = &*self.pool.get().map_err(internal_error)?; + let _ = GridRevisionSql::delete(object_id, rev_ids, conn)?; + Ok(()) + } + + fn delete_and_insert_records( + &self, + object_id: &str, + deleted_rev_ids: Option>, + inserted_records: Vec, + ) -> Result<(), Self::Error> { + let conn = self.pool.get().map_err(internal_error)?; + conn.immediate_transaction::<_, FlowyError, _>(|| { + let _ = GridRevisionSql::delete(object_id, deleted_rev_ids, &*conn)?; + let _ = self.create_revision_records(inserted_records, &*conn)?; + Ok(()) + }) + } +} + +impl SQLiteGridRevisionPersistence { + pub(crate) fn new(user_id: &str, pool: Arc) -> Self { + Self { + user_id: user_id.to_owned(), + pool, + } + } +} + +struct GridRevisionSql(); +impl GridRevisionSql { + fn create(revision_records: Vec, conn: &SqliteConnection) -> Result<(), FlowyError> { + // Batch insert: https://diesel.rs/guides/all-about-inserts.html + + let records = revision_records + .into_iter() + .map(|record| { + tracing::trace!( + "[GridRevisionSql] create revision: {}:{:?}", + record.revision.object_id, + record.revision.rev_id + ); + let rev_state: GridRevisionState = record.state.into(); + ( + dsl::object_id.eq(record.revision.object_id), + dsl::base_rev_id.eq(record.revision.base_rev_id), + dsl::rev_id.eq(record.revision.rev_id), + dsl::data.eq(record.revision.delta_data), + dsl::state.eq(rev_state), + ) + }) + .collect::>(); + + let _ = insert_or_ignore_into(dsl::grid_rev_table) + .values(&records) + .execute(conn)?; + Ok(()) + } + + fn update(changeset: RevisionChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> { + let state: GridRevisionState = changeset.state.clone().into(); + let filter = dsl::grid_rev_table + .filter(dsl::rev_id.eq(changeset.rev_id.as_ref())) + .filter(dsl::object_id.eq(changeset.object_id)); + let _ = update(filter).set(dsl::state.eq(state)).execute(conn)?; + tracing::debug!( + "[GridRevisionSql] update revision:{} state:to {:?}", + changeset.rev_id, + changeset.state + ); + Ok(()) + } + + fn read( + user_id: &str, + object_id: &str, + rev_ids: Option>, + conn: &SqliteConnection, + ) -> Result, FlowyError> { + let mut sql = dsl::grid_rev_table.filter(dsl::object_id.eq(object_id)).into_boxed(); + if let Some(rev_ids) = rev_ids { + sql = sql.filter(dsl::rev_id.eq_any(rev_ids)); + } + let rows = sql.order(dsl::rev_id.asc()).load::(conn)?; + let records = rows + .into_iter() + .map(|row| mk_revision_record_from_table(user_id, row)) + .collect::>(); + + Ok(records) + } + + fn read_with_range( + user_id: &str, + object_id: &str, + range: RevisionRange, + conn: &SqliteConnection, + ) -> Result, FlowyError> { + let rev_tables = dsl::grid_rev_table + .filter(dsl::rev_id.ge(range.start)) + .filter(dsl::rev_id.le(range.end)) + .filter(dsl::object_id.eq(object_id)) + .order(dsl::rev_id.asc()) + .load::(conn)?; + + let revisions = rev_tables + .into_iter() + .map(|table| mk_revision_record_from_table(user_id, table)) + .collect::>(); + Ok(revisions) + } + + fn delete(object_id: &str, rev_ids: Option>, conn: &SqliteConnection) -> Result<(), FlowyError> { + let mut sql = diesel::delete(dsl::grid_rev_table).into_boxed(); + sql = sql.filter(dsl::object_id.eq(object_id)); + + if let Some(rev_ids) = rev_ids { + tracing::trace!("[GridRevisionSql] Delete revision: {}:{:?}", object_id, rev_ids); + sql = sql.filter(dsl::rev_id.eq_any(rev_ids)); + } + + let affected_row = sql.execute(conn)?; + tracing::trace!("[GridRevisionSql] Delete {} rows", affected_row); + Ok(()) + } +} + +#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] +#[table_name = "grid_rev_table"] +pub(crate) struct GridRevisionTable { + id: i32, + pub(crate) object_id: String, + pub(crate) base_rev_id: i64, + pub(crate) rev_id: i64, + pub(crate) data: Vec, + pub(crate) state: GridRevisionState, +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, FromSqlRow, AsExpression)] +#[repr(i32)] +#[sql_type = "Integer"] +pub enum GridRevisionState { + Sync = 0, + Ack = 1, +} + +impl std::default::Default for GridRevisionState { + fn default() -> Self { + GridRevisionState::Sync + } +} + +impl std::convert::From for GridRevisionState { + fn from(value: i32) -> Self { + match value { + 0 => GridRevisionState::Sync, + 1 => GridRevisionState::Ack, + o => { + tracing::error!("Unsupported rev state {}, fallback to RevState::Local", o); + GridRevisionState::Sync + } + } + } +} + +impl GridRevisionState { + pub fn value(&self) -> i32 { + *self as i32 + } +} +impl_sql_integer_expression!(GridRevisionState); + +impl std::convert::From for RevisionState { + fn from(s: GridRevisionState) -> Self { + match s { + GridRevisionState::Sync => RevisionState::Sync, + GridRevisionState::Ack => RevisionState::Ack, + } + } +} + +impl std::convert::From for GridRevisionState { + fn from(s: RevisionState) -> Self { + match s { + RevisionState::Sync => GridRevisionState::Sync, + RevisionState::Ack => GridRevisionState::Ack, + } + } +} + +fn mk_revision_record_from_table(user_id: &str, table: GridRevisionTable) -> RevisionRecord { + let md5 = md5(&table.data); + let revision = Revision::new( + &table.object_id, + table.base_rev_id, + table.rev_id, + Bytes::from(table.data), + user_id, + md5, + ); + RevisionRecord { + revision, + state: table.state.into(), + write_to_disk: false, + } +} diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs index 6c3ee45f37..4fcad2d2ec 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs @@ -1,14 +1,13 @@ mod folder_rev_impl; mod grid_rev_impl; -mod text_block_rev_impl; +mod text_rev_impl; pub use folder_rev_impl::*; pub use grid_rev_impl::*; -pub use text_block_rev_impl::*; +pub use text_rev_impl::*; -use crate::RevisionRecord; use diesel::SqliteConnection; -use flowy_collaboration::entities::revision::RevisionRange; +use flowy_collaboration::entities::revision::{RevId, Revision, RevisionRange}; use flowy_error::FlowyResult; use std::fmt::Debug; @@ -48,3 +47,43 @@ pub trait RevisionDiskCache: Sync + Send { inserted_records: Vec, ) -> Result<(), Self::Error>; } + +#[derive(Clone, Debug)] +pub struct RevisionRecord { + pub revision: Revision, + pub state: RevisionState, + pub write_to_disk: bool, +} + +impl RevisionRecord { + pub fn ack(&mut self) { + self.state = RevisionState::Ack; + } +} + +pub struct RevisionChangeset { + pub(crate) object_id: String, + pub(crate) rev_id: RevId, + pub(crate) state: RevisionState, +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum RevisionState { + Sync = 0, + Ack = 1, +} + +impl RevisionState { + pub fn is_need_sync(&self) -> bool { + match self { + RevisionState::Sync => true, + RevisionState::Ack => false, + } + } +} + +impl AsRef for RevisionState { + fn as_ref(&self) -> &RevisionState { + self + } +} diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/text_block_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs similarity index 72% rename from frontend/rust-lib/flowy-sync/src/cache/disk/text_block_rev_impl.rs rename to frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs index d7b56034c3..7659ad33dc 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/text_block_rev_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs @@ -1,8 +1,9 @@ -use crate::{cache::disk::RevisionDiskCache, RevisionRecord}; +use crate::cache::disk::RevisionDiskCache; +use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; use bytes::Bytes; use diesel::{sql_types::Integer, update, SqliteConnection}; use flowy_collaboration::{ - entities::revision::{RevId, RevType, Revision, RevisionRange, RevisionState}, + entities::revision::{RevId, RevType, Revision, RevisionRange}, util::md5, }; use flowy_database::{ @@ -27,7 +28,7 @@ impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { revision_records: Vec, conn: &SqliteConnection, ) -> Result<(), Self::Error> { - let _ = RevisionTableSql::create(revision_records, conn)?; + let _ = TextRevisionSql::create(revision_records, conn)?; Ok(()) } @@ -37,7 +38,7 @@ impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { rev_ids: Option>, ) -> Result, Self::Error> { let conn = self.pool.get().map_err(internal_error)?; - let records = RevisionTableSql::read(&self.user_id, object_id, rev_ids, &*conn)?; + let records = TextRevisionSql::read(&self.user_id, object_id, rev_ids, &*conn)?; Ok(records) } @@ -47,7 +48,7 @@ impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { range: &RevisionRange, ) -> Result, Self::Error> { let conn = &*self.pool.get().map_err(internal_error)?; - let revisions = RevisionTableSql::read_with_range(&self.user_id, object_id, range.clone(), conn)?; + let revisions = TextRevisionSql::read_with_range(&self.user_id, object_id, range.clone(), conn)?; Ok(revisions) } @@ -55,7 +56,7 @@ impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { let conn = &*self.pool.get().map_err(internal_error)?; let _ = conn.immediate_transaction::<_, FlowyError, _>(|| { for changeset in changesets { - let _ = RevisionTableSql::update(changeset, conn)?; + let _ = TextRevisionSql::update(changeset, conn)?; } Ok(()) })?; @@ -64,7 +65,7 @@ impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { fn delete_revision_records(&self, object_id: &str, rev_ids: Option>) -> Result<(), Self::Error> { let conn = &*self.pool.get().map_err(internal_error)?; - let _ = RevisionTableSql::delete(object_id, rev_ids, conn)?; + let _ = TextRevisionSql::delete(object_id, rev_ids, conn)?; Ok(()) } @@ -76,7 +77,7 @@ impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { ) -> Result<(), Self::Error> { let conn = self.pool.get().map_err(internal_error)?; conn.immediate_transaction::<_, FlowyError, _>(|| { - let _ = RevisionTableSql::delete(object_id, deleted_rev_ids, &*conn)?; + let _ = TextRevisionSql::delete(object_id, deleted_rev_ids, &*conn)?; let _ = self.create_revision_records(inserted_records, &*conn)?; Ok(()) }) @@ -92,21 +93,21 @@ impl SQLiteTextBlockRevisionPersistence { } } -pub struct RevisionTableSql {} +struct TextRevisionSql {} -impl RevisionTableSql { - pub(crate) fn create(revision_records: Vec, conn: &SqliteConnection) -> Result<(), FlowyError> { +impl TextRevisionSql { + fn create(revision_records: Vec, conn: &SqliteConnection) -> Result<(), FlowyError> { // Batch insert: https://diesel.rs/guides/all-about-inserts.html let records = revision_records .into_iter() .map(|record| { tracing::trace!( - "[RevisionTable] create revision: {}:{:?}", + "[TextRevisionSql] create revision: {}:{:?}", record.revision.object_id, record.revision.rev_id ); - let rev_state: RevisionTableState = record.state.into(); + let rev_state: TextRevisionState = record.state.into(); ( dsl::doc_id.eq(record.revision.object_id), dsl::base_rev_id.eq(record.revision.base_rev_id), @@ -122,20 +123,21 @@ impl RevisionTableSql { Ok(()) } - pub(crate) fn update(changeset: RevisionChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> { + fn update(changeset: RevisionChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> { + let state: TextRevisionState = changeset.state.clone().into(); let filter = dsl::rev_table .filter(dsl::rev_id.eq(changeset.rev_id.as_ref())) .filter(dsl::doc_id.eq(changeset.object_id)); - let _ = update(filter).set(dsl::state.eq(changeset.state)).execute(conn)?; + let _ = update(filter).set(dsl::state.eq(state)).execute(conn)?; tracing::debug!( - "[RevisionTable] update revision:{} state:to {:?}", + "[TextRevisionSql] update revision:{} state:to {:?}", changeset.rev_id, changeset.state ); Ok(()) } - pub(crate) fn read( + fn read( user_id: &str, object_id: &str, rev_ids: Option>, @@ -154,7 +156,7 @@ impl RevisionTableSql { Ok(records) } - pub(crate) fn read_with_range( + fn read_with_range( user_id: &str, object_id: &str, range: RevisionRange, @@ -174,90 +176,86 @@ impl RevisionTableSql { Ok(revisions) } - pub(crate) fn delete( - object_id: &str, - rev_ids: Option>, - conn: &SqliteConnection, - ) -> Result<(), FlowyError> { + fn delete(object_id: &str, rev_ids: Option>, conn: &SqliteConnection) -> Result<(), FlowyError> { let mut sql = diesel::delete(dsl::rev_table).into_boxed(); sql = sql.filter(dsl::doc_id.eq(object_id)); if let Some(rev_ids) = rev_ids { - tracing::trace!("[RevisionTable] Delete revision: {}:{:?}", object_id, rev_ids); + tracing::trace!("[TextRevisionSql] Delete revision: {}:{:?}", object_id, rev_ids); sql = sql.filter(dsl::rev_id.eq_any(rev_ids)); } let affected_row = sql.execute(conn)?; - tracing::trace!("[RevisionTable] Delete {} rows", affected_row); + tracing::trace!("[TextRevisionSql] Delete {} rows", affected_row); Ok(()) } } #[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] #[table_name = "rev_table"] -pub(crate) struct RevisionTable { +struct RevisionTable { id: i32, - pub(crate) doc_id: String, - pub(crate) base_rev_id: i64, - pub(crate) rev_id: i64, - pub(crate) data: Vec, - pub(crate) state: RevisionTableState, - pub(crate) ty: RevTableType, // Deprecated + doc_id: String, + base_rev_id: i64, + rev_id: i64, + data: Vec, + state: TextRevisionState, + ty: RevTableType, // Deprecated } #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, FromSqlRow, AsExpression)] #[repr(i32)] #[sql_type = "Integer"] -pub enum RevisionTableState { +enum TextRevisionState { Sync = 0, Ack = 1, } -impl std::default::Default for RevisionTableState { +impl std::default::Default for TextRevisionState { fn default() -> Self { - RevisionTableState::Sync + TextRevisionState::Sync } } -impl std::convert::From for RevisionTableState { +impl std::convert::From for TextRevisionState { fn from(value: i32) -> Self { match value { - 0 => RevisionTableState::Sync, - 1 => RevisionTableState::Ack, + 0 => TextRevisionState::Sync, + 1 => TextRevisionState::Ack, o => { tracing::error!("Unsupported rev state {}, fallback to RevState::Local", o); - RevisionTableState::Sync + TextRevisionState::Sync } } } } -impl RevisionTableState { +impl TextRevisionState { pub fn value(&self) -> i32 { *self as i32 } } -impl_sql_integer_expression!(RevisionTableState); +impl_sql_integer_expression!(TextRevisionState); -impl std::convert::From for RevisionState { - fn from(s: RevisionTableState) -> Self { +impl std::convert::From for RevisionState { + fn from(s: TextRevisionState) -> Self { match s { - RevisionTableState::Sync => RevisionState::Sync, - RevisionTableState::Ack => RevisionState::Ack, + TextRevisionState::Sync => RevisionState::Sync, + TextRevisionState::Ack => RevisionState::Ack, } } } -impl std::convert::From for RevisionTableState { +impl std::convert::From for TextRevisionState { fn from(s: RevisionState) -> Self { match s { - RevisionState::Sync => RevisionTableState::Sync, - RevisionState::Ack => RevisionTableState::Ack, + RevisionState::Sync => TextRevisionState::Sync, + RevisionState::Ack => TextRevisionState::Ack, } } } -pub(crate) fn mk_revision_record_from_table(user_id: &str, table: RevisionTable) -> RevisionRecord { +fn mk_revision_record_from_table(user_id: &str, table: RevisionTable) -> RevisionRecord { let md5 = md5(&table.data); let revision = Revision::new( &table.doc_id, @@ -324,9 +322,3 @@ impl std::convert::From for RevType { } } } - -pub struct RevisionChangeset { - pub(crate) object_id: String, - pub(crate) rev_id: RevId, - pub(crate) state: RevisionTableState, -} diff --git a/frontend/rust-lib/flowy-sync/src/cache/memory.rs b/frontend/rust-lib/flowy-sync/src/cache/memory.rs index 2c99c3f08c..f709abcdd2 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/memory.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/memory.rs @@ -1,4 +1,5 @@ -use crate::{RevisionRecord, REVISION_WRITE_INTERVAL_IN_MILLIS}; +use crate::disk::RevisionRecord; +use crate::REVISION_WRITE_INTERVAL_IN_MILLIS; use dashmap::DashMap; use flowy_collaboration::entities::revision::RevisionRange; use flowy_error::{FlowyError, FlowyResult}; diff --git a/frontend/rust-lib/flowy-sync/src/cache/mod.rs b/frontend/rust-lib/flowy-sync/src/cache/mod.rs index 9ef6fb7da0..3e592c49b1 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/mod.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/mod.rs @@ -1,2 +1,2 @@ -pub(crate) mod disk; +pub mod disk; pub(crate) mod memory; diff --git a/frontend/rust-lib/flowy-sync/src/rev_manager.rs b/frontend/rust-lib/flowy-sync/src/rev_manager.rs index 5583690913..ab5d7858b3 100644 --- a/frontend/rust-lib/flowy-sync/src/rev_manager.rs +++ b/frontend/rust-lib/flowy-sync/src/rev_manager.rs @@ -1,6 +1,7 @@ +use crate::disk::RevisionState; use crate::{RevisionPersistence, WSDataProviderDataSource}; use flowy_collaboration::{ - entities::revision::{RepeatedRevision, Revision, RevisionRange, RevisionState}, + entities::revision::{RepeatedRevision, Revision, RevisionRange}, util::{pair_rev_id_from_revisions, RevIdCounter}, }; use flowy_error::{FlowyError, FlowyResult}; diff --git a/frontend/rust-lib/flowy-sync/src/rev_persistence.rs b/frontend/rust-lib/flowy-sync/src/rev_persistence.rs index 428e708916..d6b129170f 100644 --- a/frontend/rust-lib/flowy-sync/src/rev_persistence.rs +++ b/frontend/rust-lib/flowy-sync/src/rev_persistence.rs @@ -1,13 +1,12 @@ use crate::cache::{ - disk::{RevisionChangeset, RevisionDiskCache, RevisionTableState, SQLiteTextBlockRevisionPersistence}, + disk::{RevisionChangeset, RevisionDiskCache, SQLiteTextBlockRevisionPersistence}, memory::{RevisionMemoryCache, RevisionMemoryCacheDelegate}, }; - -use flowy_collaboration::entities::revision::{Revision, RevisionRange, RevisionState}; +use crate::disk::{RevisionRecord, RevisionState}; +use crate::RevisionCompact; +use flowy_collaboration::entities::revision::{Revision, RevisionRange}; use flowy_database::ConnectionPool; use flowy_error::{internal_error, FlowyError, FlowyResult}; - -use crate::RevisionCompact; use std::collections::VecDeque; use std::{borrow::Cow, sync::Arc}; use tokio::sync::RwLock; @@ -235,7 +234,7 @@ impl RevisionMemoryCacheDelegate for Arc { let changeset = RevisionChangeset { object_id: object_id.to_string(), rev_id: rev_id.into(), - state: RevisionTableState::Ack, + state: RevisionState::Ack, }; match self.update_revision_record(vec![changeset]) { Ok(_) => {} @@ -244,19 +243,6 @@ impl RevisionMemoryCacheDelegate for Arc { } } -#[derive(Clone, Debug)] -pub struct RevisionRecord { - pub revision: Revision, - pub state: RevisionState, - pub write_to_disk: bool, -} - -impl RevisionRecord { - pub fn ack(&mut self) { - self.state = RevisionState::Ack; - } -} - #[derive(Default)] struct RevisionSyncSequence(VecDeque); impl RevisionSyncSequence { diff --git a/shared-lib/flowy-collaboration/src/entities/revision.rs b/shared-lib/flowy-collaboration/src/entities/revision.rs index cd99a194a1..57276bba1b 100644 --- a/shared-lib/flowy-collaboration/src/entities/revision.rs +++ b/shared-lib/flowy-collaboration/src/entities/revision.rs @@ -215,27 +215,6 @@ pub fn md5>(data: T) -> String { md5 } -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum RevisionState { - Sync = 0, - Ack = 1, -} - -impl RevisionState { - pub fn is_need_sync(&self) -> bool { - match self { - RevisionState::Sync => true, - RevisionState::Ack => false, - } - } -} - -impl AsRef for RevisionState { - fn as_ref(&self) -> &RevisionState { - self - } -} - #[derive(Debug, ProtoBuf_Enum, Clone, Eq, PartialEq)] pub enum RevType { DeprecatedLocal = 0, diff --git a/shared-lib/flowy-collaboration/src/protobuf/model/revision.rs b/shared-lib/flowy-collaboration/src/protobuf/model/revision.rs index 079687ca44..02d1f522cf 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/model/revision.rs +++ b/shared-lib/flowy-collaboration/src/protobuf/model/revision.rs @@ -914,56 +914,6 @@ impl ::protobuf::reflect::ProtobufValue for RevisionRange { } } -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum RevisionState { - Sync = 0, - Ack = 1, -} - -impl ::protobuf::ProtobufEnum for RevisionState { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(RevisionState::Sync), - 1 => ::std::option::Option::Some(RevisionState::Ack), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [RevisionState] = &[ - RevisionState::Sync, - RevisionState::Ack, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("RevisionState", file_descriptor_proto()) - }) - } -} - -impl ::std::marker::Copy for RevisionState { -} - -impl ::std::default::Default for RevisionState { - fn default() -> Self { - RevisionState::Sync - } -} - -impl ::protobuf::reflect::ProtobufValue for RevisionState { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) - } -} - #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum RevType { DeprecatedLocal = 0, @@ -1024,8 +974,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x10RepeatedRevision\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\t.Revision\ R\x05items\"\x1d\n\x05RevId\x12\x14\n\x05value\x18\x01\x20\x01(\x03R\x05\ value\"7\n\rRevisionRange\x12\x14\n\x05start\x18\x01\x20\x01(\x03R\x05st\ - art\x12\x10\n\x03end\x18\x02\x20\x01(\x03R\x03end*\"\n\rRevisionState\ - \x12\x08\n\x04Sync\x10\0\x12\x07\n\x03Ack\x10\x01*4\n\x07RevType\x12\x13\ + art\x12\x10\n\x03end\x18\x02\x20\x01(\x03R\x03end*4\n\x07RevType\x12\x13\ \n\x0fDeprecatedLocal\x10\0\x12\x14\n\x10DeprecatedRemote\x10\x01b\x06pr\ oto3\ "; diff --git a/shared-lib/flowy-collaboration/src/protobuf/proto/revision.proto b/shared-lib/flowy-collaboration/src/protobuf/proto/revision.proto index 34c37409ab..5e899e9688 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/proto/revision.proto +++ b/shared-lib/flowy-collaboration/src/protobuf/proto/revision.proto @@ -19,10 +19,6 @@ message RevisionRange { int64 start = 1; int64 end = 2; } -enum RevisionState { - Sync = 0; - Ack = 1; -} enum RevType { DeprecatedLocal = 0; DeprecatedRemote = 1; From e11176436d4c76a0ccfaf84e004258c19d2c061d Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 11 Mar 2022 21:36:00 +0800 Subject: [PATCH 11/28] chore: grid block meta editor --- .../flowy-grid-data-model/meta.pb.dart | 296 ++++++- .../flowy-grid-data-model/meta.pbjson.dart | 50 +- frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- frontend/rust-lib/flowy-block/src/editor.rs | 6 +- frontend/rust-lib/flowy-block/src/manager.rs | 14 +- frontend/rust-lib/flowy-block/src/queue.rs | 28 +- .../2022-03-04-101530_flowy-grid/down.sql | 3 +- .../2022-03-04-101530_flowy-grid/up.sql | 9 - .../2022-03-11-025536_flowy-grid/down.sql | 3 + .../2022-03-11-025536_flowy-grid/up.sql | 18 + .../rust-lib/flowy-database/src/macros.rs | 36 + .../rust-lib/flowy-database/src/schema.rs | 12 + frontend/rust-lib/flowy-folder/src/manager.rs | 10 +- .../src/services/folder_editor.rs | 40 +- .../src/services/persistence/migration.rs | 4 +- frontend/rust-lib/flowy-grid/src/manager.rs | 5 +- .../flowy-grid/src/services/grid_editor.rs | 217 +++-- .../src/services/grid_meta_editor.rs | 125 +++ .../rust-lib/flowy-grid/src/services/mod.rs | 1 + .../flowy-sdk/src/deps_resolve/folder_deps.rs | 12 +- .../src/cache/disk/grid_meta_rev_impl.rs | 235 +++++ .../src/cache/disk/grid_rev_impl.rs | 66 +- .../rust-lib/flowy-sync/src/cache/disk/mod.rs | 9 +- .../src/cache/disk/text_rev_impl.rs | 61 +- .../rust-lib/flowy-sync/src/rev_manager.rs | 40 +- .../flowy-sync/src/rev_persistence.rs | 34 +- .../src/client_grid/block_pad.rs | 54 +- .../src/client_grid/grid_pad.rs | 149 +++- .../src/entities/grid.rs | 3 - .../src/entities/meta.rs | 43 +- .../src/protobuf/model/meta.rs | 813 ++++++++++++++++-- .../src/protobuf/proto/meta.proto | 16 +- 32 files changed, 1887 insertions(+), 529 deletions(-) create mode 100644 frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/down.sql create mode 100644 frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/up.sql create mode 100644 frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs create mode 100644 frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 924cb4addb..3b5d6f5dad 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -17,7 +17,7 @@ class GridMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: Field.create) - ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: Block.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: GridBlock.create) ..hasRequiredFields = false ; @@ -25,7 +25,7 @@ class GridMeta extends $pb.GeneratedMessage { factory GridMeta({ $core.String? gridId, $core.Iterable? fields, - $core.Iterable? blocks, + $core.Iterable? blocks, }) { final _result = create(); if (gridId != null) { @@ -73,19 +73,19 @@ class GridMeta extends $pb.GeneratedMessage { $core.List get fields => $_getList(1); @$pb.TagNumber(3) - $core.List get blocks => $_getList(2); + $core.List get blocks => $_getList(2); } -class Block extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Block', createEmptyInstance: create) +class GridBlock extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startRowIndex', $pb.PbFieldType.O3) ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowCount', $pb.PbFieldType.O3) ..hasRequiredFields = false ; - Block._() : super(); - factory Block({ + GridBlock._() : super(); + factory GridBlock({ $core.String? id, $core.int? startRowIndex, $core.int? rowCount, @@ -102,26 +102,26 @@ class Block extends $pb.GeneratedMessage { } return _result; } - factory Block.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Block.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory GridBlock.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlock.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - Block clone() => Block()..mergeFromMessage(this); + GridBlock clone() => GridBlock()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - Block copyWith(void Function(Block) updates) => super.copyWith((message) => updates(message as Block)) as Block; // ignore: deprecated_member_use + GridBlock copyWith(void Function(GridBlock) updates) => super.copyWith((message) => updates(message as GridBlock)) as GridBlock; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static Block create() => Block._(); - Block createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static GridBlock create() => GridBlock._(); + GridBlock createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static Block getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static Block? _defaultInstance; + static GridBlock getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlock? _defaultInstance; @$pb.TagNumber(1) $core.String get id => $_getSZ(0); @@ -151,15 +151,15 @@ class Block extends $pb.GeneratedMessage { void clearRowCount() => clearField(3); } -class BlockMeta extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlockMeta', createEmptyInstance: create) +class GridBlockMeta extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) ..hasRequiredFields = false ; - BlockMeta._() : super(); - factory BlockMeta({ + GridBlockMeta._() : super(); + factory GridBlockMeta({ $core.String? blockId, $core.Iterable? rows, }) { @@ -172,26 +172,26 @@ class BlockMeta extends $pb.GeneratedMessage { } return _result; } - factory BlockMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory BlockMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory GridBlockMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlockMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - BlockMeta clone() => BlockMeta()..mergeFromMessage(this); + GridBlockMeta clone() => GridBlockMeta()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - BlockMeta copyWith(void Function(BlockMeta) updates) => super.copyWith((message) => updates(message as BlockMeta)) as BlockMeta; // ignore: deprecated_member_use + GridBlockMeta copyWith(void Function(GridBlockMeta) updates) => super.copyWith((message) => updates(message as GridBlockMeta)) as GridBlockMeta; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static BlockMeta create() => BlockMeta._(); - BlockMeta createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static GridBlockMeta create() => GridBlockMeta._(); + GridBlockMeta createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static BlockMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static BlockMeta? _defaultInstance; + static GridBlockMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlockMeta? _defaultInstance; @$pb.TagNumber(1) $core.String get blockId => $_getSZ(0); @@ -394,6 +394,244 @@ class RepeatedField extends $pb.GeneratedMessage { $core.List get items => $_getList(0); } +enum FieldChangeset_OneOfName { + name, + notSet +} + +enum FieldChangeset_OneOfDesc { + desc, + notSet +} + +enum FieldChangeset_OneOfFieldType { + fieldType, + notSet +} + +enum FieldChangeset_OneOfFrozen { + frozen, + notSet +} + +enum FieldChangeset_OneOfVisibility { + visibility, + notSet +} + +enum FieldChangeset_OneOfWidth { + width, + notSet +} + +enum FieldChangeset_OneOfTypeOptions { + typeOptions, + notSet +} + +class FieldChangeset extends $pb.GeneratedMessage { + static const $core.Map<$core.int, FieldChangeset_OneOfName> _FieldChangeset_OneOfNameByTag = { + 2 : FieldChangeset_OneOfName.name, + 0 : FieldChangeset_OneOfName.notSet + }; + static const $core.Map<$core.int, FieldChangeset_OneOfDesc> _FieldChangeset_OneOfDescByTag = { + 3 : FieldChangeset_OneOfDesc.desc, + 0 : FieldChangeset_OneOfDesc.notSet + }; + static const $core.Map<$core.int, FieldChangeset_OneOfFieldType> _FieldChangeset_OneOfFieldTypeByTag = { + 4 : FieldChangeset_OneOfFieldType.fieldType, + 0 : FieldChangeset_OneOfFieldType.notSet + }; + static const $core.Map<$core.int, FieldChangeset_OneOfFrozen> _FieldChangeset_OneOfFrozenByTag = { + 5 : FieldChangeset_OneOfFrozen.frozen, + 0 : FieldChangeset_OneOfFrozen.notSet + }; + static const $core.Map<$core.int, FieldChangeset_OneOfVisibility> _FieldChangeset_OneOfVisibilityByTag = { + 6 : FieldChangeset_OneOfVisibility.visibility, + 0 : FieldChangeset_OneOfVisibility.notSet + }; + static const $core.Map<$core.int, FieldChangeset_OneOfWidth> _FieldChangeset_OneOfWidthByTag = { + 7 : FieldChangeset_OneOfWidth.width, + 0 : FieldChangeset_OneOfWidth.notSet + }; + static const $core.Map<$core.int, FieldChangeset_OneOfTypeOptions> _FieldChangeset_OneOfTypeOptionsByTag = { + 8 : FieldChangeset_OneOfTypeOptions.typeOptions, + 0 : FieldChangeset_OneOfTypeOptions.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldChangeset', createEmptyInstance: create) + ..oo(0, [2]) + ..oo(1, [3]) + ..oo(2, [4]) + ..oo(3, [5]) + ..oo(4, [6]) + ..oo(5, [7]) + ..oo(6, [8]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') + ..e(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values) + ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') + ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') + ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) + ..aOM(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', subBuilder: AnyData.create) + ..hasRequiredFields = false + ; + + FieldChangeset._() : super(); + factory FieldChangeset({ + $core.String? fieldId, + $core.String? name, + $core.String? desc, + FieldType? fieldType, + $core.bool? frozen, + $core.bool? visibility, + $core.int? width, + AnyData? typeOptions, + }) { + final _result = create(); + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (name != null) { + _result.name = name; + } + if (desc != null) { + _result.desc = desc; + } + if (fieldType != null) { + _result.fieldType = fieldType; + } + if (frozen != null) { + _result.frozen = frozen; + } + if (visibility != null) { + _result.visibility = visibility; + } + if (width != null) { + _result.width = width; + } + if (typeOptions != null) { + _result.typeOptions = typeOptions; + } + return _result; + } + factory FieldChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory FieldChangeset.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + FieldChangeset clone() => FieldChangeset()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + FieldChangeset copyWith(void Function(FieldChangeset) updates) => super.copyWith((message) => updates(message as FieldChangeset)) as FieldChangeset; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static FieldChangeset create() => FieldChangeset._(); + FieldChangeset createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static FieldChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static FieldChangeset? _defaultInstance; + + FieldChangeset_OneOfName whichOneOfName() => _FieldChangeset_OneOfNameByTag[$_whichOneof(0)]!; + void clearOneOfName() => clearField($_whichOneof(0)); + + FieldChangeset_OneOfDesc whichOneOfDesc() => _FieldChangeset_OneOfDescByTag[$_whichOneof(1)]!; + void clearOneOfDesc() => clearField($_whichOneof(1)); + + FieldChangeset_OneOfFieldType whichOneOfFieldType() => _FieldChangeset_OneOfFieldTypeByTag[$_whichOneof(2)]!; + void clearOneOfFieldType() => clearField($_whichOneof(2)); + + FieldChangeset_OneOfFrozen whichOneOfFrozen() => _FieldChangeset_OneOfFrozenByTag[$_whichOneof(3)]!; + void clearOneOfFrozen() => clearField($_whichOneof(3)); + + FieldChangeset_OneOfVisibility whichOneOfVisibility() => _FieldChangeset_OneOfVisibilityByTag[$_whichOneof(4)]!; + void clearOneOfVisibility() => clearField($_whichOneof(4)); + + FieldChangeset_OneOfWidth whichOneOfWidth() => _FieldChangeset_OneOfWidthByTag[$_whichOneof(5)]!; + void clearOneOfWidth() => clearField($_whichOneof(5)); + + FieldChangeset_OneOfTypeOptions whichOneOfTypeOptions() => _FieldChangeset_OneOfTypeOptionsByTag[$_whichOneof(6)]!; + void clearOneOfTypeOptions() => clearField($_whichOneof(6)); + + @$pb.TagNumber(1) + $core.String get fieldId => $_getSZ(0); + @$pb.TagNumber(1) + set fieldId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasFieldId() => $_has(0); + @$pb.TagNumber(1) + void clearFieldId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get name => $_getSZ(1); + @$pb.TagNumber(2) + set name($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasName() => $_has(1); + @$pb.TagNumber(2) + void clearName() => clearField(2); + + @$pb.TagNumber(3) + $core.String get desc => $_getSZ(2); + @$pb.TagNumber(3) + set desc($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasDesc() => $_has(2); + @$pb.TagNumber(3) + void clearDesc() => clearField(3); + + @$pb.TagNumber(4) + FieldType get fieldType => $_getN(3); + @$pb.TagNumber(4) + set fieldType(FieldType v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasFieldType() => $_has(3); + @$pb.TagNumber(4) + void clearFieldType() => clearField(4); + + @$pb.TagNumber(5) + $core.bool get frozen => $_getBF(4); + @$pb.TagNumber(5) + set frozen($core.bool v) { $_setBool(4, v); } + @$pb.TagNumber(5) + $core.bool hasFrozen() => $_has(4); + @$pb.TagNumber(5) + void clearFrozen() => clearField(5); + + @$pb.TagNumber(6) + $core.bool get visibility => $_getBF(5); + @$pb.TagNumber(6) + set visibility($core.bool v) { $_setBool(5, v); } + @$pb.TagNumber(6) + $core.bool hasVisibility() => $_has(5); + @$pb.TagNumber(6) + void clearVisibility() => clearField(6); + + @$pb.TagNumber(7) + $core.int get width => $_getIZ(6); + @$pb.TagNumber(7) + set width($core.int v) { $_setSignedInt32(6, v); } + @$pb.TagNumber(7) + $core.bool hasWidth() => $_has(6); + @$pb.TagNumber(7) + void clearWidth() => clearField(7); + + @$pb.TagNumber(8) + AnyData get typeOptions => $_getN(7); + @$pb.TagNumber(8) + set typeOptions(AnyData v) { setField(8, v); } + @$pb.TagNumber(8) + $core.bool hasTypeOptions() => $_has(7); + @$pb.TagNumber(8) + void clearTypeOptions() => clearField(8); + @$pb.TagNumber(8) + AnyData ensureTypeOptions() => $_ensure(7); +} + class AnyData extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AnyData', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeId') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 5685a4c17b..c955a005fb 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -29,15 +29,15 @@ const GridMeta$json = const { '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.Field', '10': 'fields'}, - const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.Block', '10': 'blocks'}, + const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlock', '10': 'blocks'}, ], }; /// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIeCgZibG9ja3MYAyADKAsyBi5CbG9ja1IGYmxvY2tz'); -@$core.Deprecated('Use blockDescriptor instead') -const Block$json = const { - '1': 'Block', +final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIiCgZibG9ja3MYAyADKAsyCi5HcmlkQmxvY2tSBmJsb2Nrcw=='); +@$core.Deprecated('Use gridBlockDescriptor instead') +const GridBlock$json = const { + '1': 'GridBlock', '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'start_row_index', '3': 2, '4': 1, '5': 5, '10': 'startRowIndex'}, @@ -45,19 +45,19 @@ const Block$json = const { ], }; -/// Descriptor for `Block`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List blockDescriptor = $convert.base64Decode('CgVCbG9jaxIOCgJpZBgBIAEoCVICaWQSJgoPc3RhcnRfcm93X2luZGV4GAIgASgFUg1zdGFydFJvd0luZGV4EhsKCXJvd19jb3VudBgDIAEoBVIIcm93Q291bnQ='); -@$core.Deprecated('Use blockMetaDescriptor instead') -const BlockMeta$json = const { - '1': 'BlockMeta', +/// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSDgoCaWQYASABKAlSAmlkEiYKD3N0YXJ0X3Jvd19pbmRleBgCIAEoBVINc3RhcnRSb3dJbmRleBIbCglyb3dfY291bnQYAyABKAVSCHJvd0NvdW50'); +@$core.Deprecated('Use gridBlockMetaDescriptor instead') +const GridBlockMeta$json = const { + '1': 'GridBlockMeta', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, ], }; -/// Descriptor for `BlockMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List blockMetaDescriptor = $convert.base64Decode('CglCbG9ja01ldGESGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSHAoEcm93cxgCIAMoCzIILlJvd01ldGFSBHJvd3M='); +/// Descriptor for `GridBlockMeta`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockMetaDescriptor = $convert.base64Decode('Cg1HcmlkQmxvY2tNZXRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEhwKBHJvd3MYAiADKAsyCC5Sb3dNZXRhUgRyb3dz'); @$core.Deprecated('Use fieldDescriptor instead') const Field$json = const { '1': 'Field', @@ -85,6 +85,32 @@ const RepeatedField$json = const { /// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z'); +@$core.Deprecated('Use fieldChangesetDescriptor instead') +const FieldChangeset$json = const { + '1': 'FieldChangeset', + '2': const [ + const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'name', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'name'}, + const {'1': 'desc', '3': 3, '4': 1, '5': 9, '9': 1, '10': 'desc'}, + const {'1': 'field_type', '3': 4, '4': 1, '5': 14, '6': '.FieldType', '9': 2, '10': 'fieldType'}, + const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '9': 3, '10': 'frozen'}, + const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '9': 4, '10': 'visibility'}, + const {'1': 'width', '3': 7, '4': 1, '5': 5, '9': 5, '10': 'width'}, + const {'1': 'type_options', '3': 8, '4': 1, '5': 11, '6': '.AnyData', '9': 6, '10': 'typeOptions'}, + ], + '8': const [ + const {'1': 'one_of_name'}, + const {'1': 'one_of_desc'}, + const {'1': 'one_of_field_type'}, + const {'1': 'one_of_frozen'}, + const {'1': 'one_of_visibility'}, + const {'1': 'one_of_width'}, + const {'1': 'one_of_type_options'}, + ], +}; + +/// Descriptor for `FieldChangeset`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldChangesetDescriptor = $convert.base64Decode('Cg5GaWVsZENoYW5nZXNldBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBIUCgRuYW1lGAIgASgJSABSBG5hbWUSFAoEZGVzYxgDIAEoCUgBUgRkZXNjEisKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVIAlIJZmllbGRUeXBlEhgKBmZyb3plbhgFIAEoCEgDUgZmcm96ZW4SIAoKdmlzaWJpbGl0eRgGIAEoCEgEUgp2aXNpYmlsaXR5EhYKBXdpZHRoGAcgASgFSAVSBXdpZHRoEi0KDHR5cGVfb3B0aW9ucxgIIAEoCzIILkFueURhdGFIBlILdHlwZU9wdGlvbnNCDQoLb25lX29mX25hbWVCDQoLb25lX29mX2Rlc2NCEwoRb25lX29mX2ZpZWxkX3R5cGVCDwoNb25lX29mX2Zyb3plbkITChFvbmVfb2ZfdmlzaWJpbGl0eUIOCgxvbmVfb2Zfd2lkdGhCFQoTb25lX29mX3R5cGVfb3B0aW9ucw=='); @$core.Deprecated('Use anyDataDescriptor instead') const AnyData$json = const { '1': 'AnyData', diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 96755db623..046fd85668 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [lib] name = "dart_ffi" # this value will change depending on the target os -# default staticlib -crate-type = ["staticlib"] +# default cdylib +crate-type = ["cdylib"] [dependencies] diff --git a/frontend/rust-lib/flowy-block/src/editor.rs b/frontend/rust-lib/flowy-block/src/editor.rs index d7977c19db..fa3c1c757c 100644 --- a/frontend/rust-lib/flowy-block/src/editor.rs +++ b/frontend/rust-lib/flowy-block/src/editor.rs @@ -1,4 +1,4 @@ -use crate::queue::BlockRevisionCompact; +use crate::queue::TextBlockRevisionCompactor; use crate::web_socket::{make_block_ws_manager, EditorCommandSender}; use crate::{ errors::FlowyError, @@ -40,9 +40,7 @@ impl ClientTextBlockEditor { rev_web_socket: Arc, cloud_service: Arc, ) -> FlowyResult> { - let document_info = rev_manager - .load::(cloud_service) - .await?; + let document_info = rev_manager.load::(cloud_service).await?; let delta = document_info.delta()?; let rev_manager = Arc::new(rev_manager); let doc_id = doc_id.to_string(); diff --git a/frontend/rust-lib/flowy-block/src/manager.rs b/frontend/rust-lib/flowy-block/src/manager.rs index 091ca31bec..a08dc9b7b1 100644 --- a/frontend/rust-lib/flowy-block/src/manager.rs +++ b/frontend/rust-lib/flowy-block/src/manager.rs @@ -8,6 +8,7 @@ use flowy_collaboration::entities::{ }; use flowy_database::ConnectionPool; use flowy_error::FlowyResult; +use flowy_sync::disk::SQLiteTextBlockRevisionPersistence; use flowy_sync::{RevisionCloudService, RevisionManager, RevisionPersistence, RevisionWebSocket}; use lib_infra::future::FutureResult; use std::{convert::TryInto, sync::Arc}; @@ -84,7 +85,7 @@ impl TextBlockManager { let doc_id = doc_id.as_ref().to_owned(); let db_pool = self.user.db_pool()?; // Maybe we could save the block to disk without creating the RevisionManager - let rev_manager = self.make_block_rev_manager(&doc_id, db_pool)?; + let rev_manager = self.make_rev_manager(&doc_id, db_pool)?; let _ = rev_manager.reset_object(revisions).await?; Ok(()) } @@ -111,20 +112,20 @@ impl TextBlockManager { match self.editor_map.get(block_id) { None => { let db_pool = self.user.db_pool()?; - self.make_block_editor(block_id, db_pool).await + self.make_text_block_editor(block_id, db_pool).await } Some(editor) => Ok(editor), } } - async fn make_block_editor( + async fn make_text_block_editor( &self, block_id: &str, pool: Arc, ) -> Result, FlowyError> { let user = self.user.clone(); let token = self.user.token()?; - let rev_manager = self.make_block_rev_manager(block_id, pool.clone())?; + let rev_manager = self.make_rev_manager(block_id, pool.clone())?; let cloud_service = Arc::new(TextBlockRevisionCloudService { token, server: self.cloud_service.clone(), @@ -135,9 +136,10 @@ impl TextBlockManager { Ok(doc_editor) } - fn make_block_rev_manager(&self, doc_id: &str, pool: Arc) -> Result { + fn make_rev_manager(&self, doc_id: &str, pool: Arc) -> Result { let user_id = self.user.user_id()?; - let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, doc_id, pool)); + let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(&user_id, pool)); + let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, doc_id, disk_cache)); Ok(RevisionManager::new(&user_id, doc_id, rev_persistence)) } } diff --git a/frontend/rust-lib/flowy-block/src/queue.rs b/frontend/rust-lib/flowy-block/src/queue.rs index aaaca7dbb4..c7683e9f0f 100644 --- a/frontend/rust-lib/flowy-block/src/queue.rs +++ b/frontend/rust-lib/flowy-block/src/queue.rs @@ -1,6 +1,7 @@ use crate::web_socket::EditorCommandReceiver; use crate::TextBlockUser; use async_stream::stream; +use bytes::Bytes; use flowy_collaboration::util::make_delta_from_revisions; use flowy_collaboration::{ client_document::{history::UndoResult, ClientDocument}, @@ -8,8 +9,9 @@ use flowy_collaboration::{ errors::CollaborateError, }; use flowy_error::{FlowyError, FlowyResult}; -use flowy_sync::{DeltaMD5, RevisionCompact, RevisionManager, RichTextTransformDeltas, TransformDeltas}; +use flowy_sync::{DeltaMD5, RevisionCompactor, RevisionManager, RichTextTransformDeltas, TransformDeltas}; use futures::stream::StreamExt; +use lib_ot::core::{Attributes, Delta}; use lib_ot::{ core::{Interval, OperationTransformable}, rich_text::{RichTextAttribute, RichTextAttributes, RichTextDelta}, @@ -187,31 +189,17 @@ impl EditBlockQueue { ); let _ = self .rev_manager - .add_local_revision::(&revision) + .add_local_revision(&revision, Box::new(TextBlockRevisionCompactor())) .await?; Ok(rev_id.into()) } } -pub(crate) struct BlockRevisionCompact(); -impl RevisionCompact for BlockRevisionCompact { - fn compact_revisions(user_id: &str, object_id: &str, mut revisions: Vec) -> FlowyResult { - if revisions.is_empty() { - return Err(FlowyError::internal().context("Can't compact the empty block's revisions")); - } - - if revisions.len() == 1 { - return Ok(revisions.pop().unwrap()); - } - - let first_revision = revisions.first().unwrap(); - let last_revision = revisions.last().unwrap(); - - let (base_rev_id, rev_id) = first_revision.pair_rev_id(); - let md5 = last_revision.md5.clone(); +pub(crate) struct TextBlockRevisionCompactor(); +impl RevisionCompactor for TextBlockRevisionCompactor { + fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { let delta = make_delta_from_revisions::(revisions)?; - let delta_data = delta.to_bytes(); - Ok(Revision::new(object_id, base_rev_id, rev_id, delta_data, user_id, md5)) + Ok(delta.to_bytes()) } } diff --git a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql index 1447085d7f..96473ec177 100644 --- a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql +++ b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql @@ -1,3 +1,2 @@ -- This file should undo anything in `up.sql` -DROP TABLE kv_table; -DROP TABLE grid_rev_table; \ No newline at end of file +DROP TABLE kv_table; \ No newline at end of file diff --git a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql index c8b592109b..edde5d7dfa 100644 --- a/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql +++ b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql @@ -2,13 +2,4 @@ CREATE TABLE kv_table ( key TEXT NOT NULL PRIMARY KEY, value BLOB NOT NULL DEFAULT (x'') -); - -CREATE TABLE grid_rev_table ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - object_id TEXT NOT NULL DEFAULT '', - base_rev_id BIGINT NOT NULL DEFAULT 0, - rev_id BIGINT NOT NULL DEFAULT 0, - data BLOB NOT NULL DEFAULT (x''), - state INTEGER NOT NULL DEFAULT 0 ); \ No newline at end of file diff --git a/frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/down.sql b/frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/down.sql new file mode 100644 index 0000000000..9d48f0fb8a --- /dev/null +++ b/frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/down.sql @@ -0,0 +1,3 @@ +-- This file should undo anything in `up.sql` +DROP TABLE grid_rev_table; +DROP TABLE grid_meta_rev_table; \ No newline at end of file diff --git a/frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/up.sql b/frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/up.sql new file mode 100644 index 0000000000..4ce278ec8f --- /dev/null +++ b/frontend/rust-lib/flowy-database/migrations/2022-03-11-025536_flowy-grid/up.sql @@ -0,0 +1,18 @@ +-- Your SQL goes here +CREATE TABLE grid_rev_table ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + object_id TEXT NOT NULL DEFAULT '', + base_rev_id BIGINT NOT NULL DEFAULT 0, + rev_id BIGINT NOT NULL DEFAULT 0, + data BLOB NOT NULL DEFAULT (x''), + state INTEGER NOT NULL DEFAULT 0 +); + +CREATE TABLE grid_meta_rev_table ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + object_id TEXT NOT NULL DEFAULT '', + base_rev_id BIGINT NOT NULL DEFAULT 0, + rev_id BIGINT NOT NULL DEFAULT 0, + data BLOB NOT NULL DEFAULT (x''), + state INTEGER NOT NULL DEFAULT 0 +); \ No newline at end of file diff --git a/frontend/rust-lib/flowy-database/src/macros.rs b/frontend/rust-lib/flowy-database/src/macros.rs index 9ef9740fee..e1534bf25f 100644 --- a/frontend/rust-lib/flowy-database/src/macros.rs +++ b/frontend/rust-lib/flowy-database/src/macros.rs @@ -160,3 +160,39 @@ macro_rules! impl_sql_integer_expression { } }; } + +#[macro_export] +macro_rules! impl_rev_state_map { + ($target:ident) => { + impl std::convert::From for $target { + fn from(value: i32) -> Self { + match value { + 0 => $target::Sync, + 1 => $target::Ack, + o => { + tracing::error!("Unsupported rev state {}, fallback to RevState::Local", o); + $target::Sync + } + } + } + } + + impl std::convert::From<$target> for RevisionState { + fn from(s: $target) -> Self { + match s { + $target::Sync => RevisionState::Sync, + $target::Ack => RevisionState::Ack, + } + } + } + + impl std::convert::From for $target { + fn from(s: RevisionState) -> Self { + match s { + RevisionState::Sync => $target::Sync, + RevisionState::Ack => $target::Ack, + } + } + } + }; +} diff --git a/frontend/rust-lib/flowy-database/src/schema.rs b/frontend/rust-lib/flowy-database/src/schema.rs index 7397f5b704..6be116e806 100644 --- a/frontend/rust-lib/flowy-database/src/schema.rs +++ b/frontend/rust-lib/flowy-database/src/schema.rs @@ -21,6 +21,17 @@ table! { } } +table! { + grid_meta_rev_table (id) { + id -> Integer, + object_id -> Text, + base_rev_id -> BigInt, + rev_id -> BigInt, + data -> Binary, + state -> Integer, + } +} + table! { grid_rev_table (id) { id -> Integer, @@ -102,6 +113,7 @@ table! { allow_tables_to_appear_in_same_query!( app_table, doc_table, + grid_meta_rev_table, grid_rev_table, kv_table, rev_table, diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index b41539d628..3ccb00466e 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -17,7 +17,8 @@ use flowy_collaboration::{client_folder::FolderPad, entities::ws_data::ServerRev use flowy_error::FlowyError; use flowy_folder_data_model::entities::view::ViewDataType; use flowy_folder_data_model::user_default; -use flowy_sync::RevisionWebSocket; +use flowy_sync::disk::SQLiteTextBlockRevisionPersistence; +use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; use lazy_static::lazy_static; use lib_infra::future::FutureResult; use std::{collections::HashMap, convert::TryInto, fmt::Formatter, sync::Arc}; @@ -163,7 +164,12 @@ impl FolderManager { let _ = self.persistence.initialize(user_id, &folder_id).await?; let pool = self.persistence.db_pool()?; - let folder_editor = ClientFolderEditor::new(user_id, &folder_id, token, pool, self.web_socket.clone()).await?; + let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(&user_id, pool)); + 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?; *self.folder_editor.write().await = Some(Arc::new(folder_editor)); let _ = self.app_controller.initialize()?; 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 536eef4c9f..203c7c4cec 100644 --- a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs +++ b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs @@ -5,14 +5,16 @@ use flowy_collaboration::{ }; use crate::manager::FolderId; +use bytes::Bytes; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; +use flowy_sync::disk::RevisionDiskCache; use flowy_sync::{ - RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder, RevisionPersistence, + RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, RevisionWebSocket, RevisionWebSocketManager, }; use lib_infra::future::FutureResult; -use lib_ot::core::PlainTextAttributes; +use lib_ot::core::{Delta, PlainTextAttributes}; use lib_sqlite::ConnectionPool; use parking_lot::RwLock; use std::sync::Arc; @@ -30,19 +32,13 @@ impl ClientFolderEditor { user_id: &str, folder_id: &FolderId, token: &str, - pool: Arc, + mut rev_manager: RevisionManager, web_socket: Arc, ) -> FlowyResult { - let rev_persistence = Arc::new(RevisionPersistence::new(user_id, folder_id.as_ref(), pool)); - let mut rev_manager = RevisionManager::new(user_id, folder_id.as_ref(), rev_persistence); let cloud = Arc::new(FolderRevisionCloudService { token: token.to_string(), }); - let folder = Arc::new(RwLock::new( - rev_manager - .load::(cloud) - .await?, - )); + let folder = Arc::new(RwLock::new(rev_manager.load::(cloud).await?)); let rev_manager = Arc::new(rev_manager); let ws_manager = make_folder_ws_manager( user_id, @@ -86,7 +82,7 @@ impl ClientFolderEditor { ); let _ = futures::executor::block_on(async { self.rev_manager - .add_local_revision::(&revision) + .add_local_revision(&revision, Box::new(FolderRevisionCompactor())) .await })?; Ok(()) @@ -128,24 +124,10 @@ impl ClientFolderEditor { } } -struct FolderRevisionCompact(); -impl RevisionCompact for FolderRevisionCompact { - fn compact_revisions(user_id: &str, object_id: &str, mut revisions: Vec) -> FlowyResult { - if revisions.is_empty() { - return Err(FlowyError::internal().context("Can't compact the empty folder's revisions")); - } - - if revisions.len() == 1 { - return Ok(revisions.pop().unwrap()); - } - - let first_revision = revisions.first().unwrap(); - let last_revision = revisions.last().unwrap(); - - let (base_rev_id, rev_id) = first_revision.pair_rev_id(); - let md5 = last_revision.md5.clone(); +struct FolderRevisionCompactor(); +impl RevisionCompactor for FolderRevisionCompactor { + fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { let delta = make_delta_from_revisions::(revisions)?; - let delta_data = delta.to_bytes(); - Ok(Revision::new(object_id, base_rev_id, rev_id, delta_data, user_id, md5)) + Ok(delta.to_bytes()) } } diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs index 3f499fc45f..20e6d71c66 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs @@ -11,6 +11,7 @@ use flowy_folder_data_model::entities::{ view::{RepeatedView, View}, workspace::Workspace, }; +use flowy_sync::disk::SQLiteTextBlockRevisionPersistence; use flowy_sync::{RevisionLoader, RevisionPersistence}; use std::sync::Arc; @@ -87,7 +88,8 @@ impl FolderMigration { return Ok(None); } let pool = self.database.db_pool()?; - let rev_persistence = Arc::new(RevisionPersistence::new(user_id, folder_id.as_ref(), pool.clone())); + let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(&user_id, pool)); + let rev_persistence = Arc::new(RevisionPersistence::new(user_id, folder_id.as_ref(), disk_cache)); let (revisions, _) = RevisionLoader { object_id: folder_id.as_ref().to_owned(), user_id: self.user_id.clone(), diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 83c12b2b78..6c5aa8236a 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -7,6 +7,7 @@ use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{Field, RowMeta}; use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; +use flowy_sync::disk::SQLiteGridRevisionPersistence; use lib_sqlite::ConnectionPool; use parking_lot::RwLock; use std::sync::Arc; @@ -104,7 +105,9 @@ impl GridManager { fn make_grid_rev_manager(&self, grid_id: &str, pool: Arc) -> FlowyResult { let user_id = self.grid_user.user_id()?; - let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, grid_id, pool)); + + let disk_cache = Arc::new(SQLiteGridRevisionPersistence::new(&user_id, pool)); + let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, grid_id, disk_cache)); let rev_manager = RevisionManager::new(&user_id, grid_id, rev_persistence); Ok(rev_manager) } 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 9bc7b6da05..4fb93c16b2 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -2,6 +2,8 @@ use crate::manager::GridUser; use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use crate::services::stringify::stringify_deserialize; +use crate::services::grid_meta_editor::ClientGridBlockMetaEditor; +use bytes::Bytes; use dashmap::DashMap; use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; use flowy_collaboration::entities::revision::Revision; @@ -10,10 +12,10 @@ use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ Cell, CellMeta, Field, Grid, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, RowMeta, }; -use flowy_sync::{RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder}; +use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; use lib_infra::uuid; -use lib_ot::core::PlainTextAttributes; +use lib_ot::core::{Delta, PlainTextAttributes}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; use std::sync::Arc; @@ -24,10 +26,8 @@ pub struct ClientGridEditor { user: Arc, grid_meta_pad: Arc>, rev_manager: Arc, + block_meta_manager: Arc, kv_persistence: Arc, - - field_map: DashMap, - cell_map: DashMap, } impl ClientGridEditor { @@ -39,50 +39,22 @@ impl ClientGridEditor { ) -> FlowyResult> { let token = user.token()?; let cloud = Arc::new(GridRevisionCloudService { token }); - let grid_pad = rev_manager.load::(cloud).await?; + let grid_pad = rev_manager.load::(cloud).await?; let rev_manager = Arc::new(rev_manager); - let field_map = load_all_fields(&grid_pad, &kv_persistence).await?; let grid_meta_pad = Arc::new(RwLock::new(grid_pad)); - let cell_map = DashMap::new(); + let block_meta_manager = Arc::new(GridBlockMetaEditorManager::new()); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), user, grid_meta_pad, rev_manager, + block_meta_manager, kv_persistence, - field_map, - cell_map, })) } - pub async fn create_empty_row(&self) -> FlowyResult<()> { - let row = RowMeta::new(&uuid(), &self.grid_id, vec![]); - self.create_row(row).await?; - Ok(()) - } - - async fn create_row(&self, row: RowMeta) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.create_row(row)?)).await?; - // self.cell_map.insert(row.id.clone(), row.clone()); - // let _ = self.kv_persistence.set(row)?; - Ok(()) - } - - pub async fn delete_rows(&self, ids: Vec) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.delete_rows(&ids)?)).await?; - // let _ = self.kv.batch_delete(ids)?; - Ok(()) - } - - // pub async fn update_row(&self, cell: Cell) -> FlowyResult<()> { - // match self.cell_map.get(&cell.id) { - // None => Err(FlowyError::internal().context(format!("Can't find cell with id: {}", cell.id))), - // Some(raw_cell) => {} - // } - // } - pub async fn create_field(&mut self, field: Field) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.create_field(field)?)).await?; Ok(()) @@ -90,76 +62,38 @@ impl ClientGridEditor { pub async fn delete_field(&mut self, field_id: &str) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?; - // let _ = self.kv.remove(field_id)?; Ok(()) } - pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult { - let ids = row_orders - .items - .into_iter() - .map(|row_order| row_order.row_id) - .collect::>(); - let row_metas: Vec = self.kv_persistence.batch_get(ids)?; - - let make_cell = |field_id: String, raw_cell: CellMeta| { - let some_field = self.field_map.get(&field_id); - if some_field.is_none() { - tracing::error!("Can't find the field with {}", field_id); - return None; - } - self.cell_map.insert(raw_cell.id.clone(), raw_cell.clone()); - - let field = some_field.unwrap(); - match stringify_deserialize(raw_cell.data, field.value()) { - Ok(content) => { - let cell = Cell { - id: raw_cell.id, - field_id: field_id.clone(), - content, - }; - Some((field_id, cell)) - } - Err(_) => None, - } - }; - - let rows = row_metas - .into_par_iter() - .map(|row_meta| { - let mut row = Row { - id: row_meta.id.clone(), - cell_by_field_id: Default::default(), - height: row_meta.height, - }; - row.cell_by_field_id = row_meta - .cell_by_field_id - .into_par_iter() - .flat_map(|(field_id, raw_cell)| make_cell(field_id, raw_cell)) - .collect::>(); - row - }) - .collect::>(); - - Ok(rows.into()) + pub async fn create_empty_row(&self) -> FlowyResult<()> { + // let _ = self.modify(|grid| { + // + // + // grid.blocks + // + // }).await?; + todo!() } - pub async fn get_fields(&self, field_orders: RepeatedFieldOrder) -> FlowyResult { - let fields = field_orders - .iter() - .flat_map(|field_order| match self.field_map.get(&field_order.field_id) { - None => { - tracing::error!("Can't find the field with {}", field_order.field_id); - None - } - Some(field) => Some(field.value().clone()), - }) - .collect::>(); - Ok(fields.into()) + async fn create_row(&self, row: RowMeta) -> FlowyResult<()> { + todo!() + } + + pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult { + todo!() + } + + pub async fn delete_rows(&self, ids: Vec) -> FlowyResult<()> { + todo!() } pub async fn grid_data(&self) -> Grid { - self.grid_meta_pad.read().await.grid_data() + todo!() + } + + pub async fn get_fields(&self, field_orders: RepeatedFieldOrder) -> FlowyResult { + let fields = self.grid_meta_pad.read().await.get_fields(field_orders)?; + Ok(fields) } pub async fn delta_str(&self) -> String { @@ -195,7 +129,7 @@ impl ClientGridEditor { ); let _ = self .rev_manager - .add_local_revision::(&revision) + .add_local_revision(&revision, Box::new(GridRevisionCompactor())) .await?; Ok(()) } @@ -241,24 +175,73 @@ impl RevisionCloudService for GridRevisionCloudService { } } -struct GridRevisionCompact(); -impl RevisionCompact for GridRevisionCompact { - fn compact_revisions(user_id: &str, object_id: &str, mut revisions: Vec) -> FlowyResult { - if revisions.is_empty() { - return Err(FlowyError::internal().context("Can't compact the empty folder's revisions")); - } - - if revisions.len() == 1 { - return Ok(revisions.pop().unwrap()); - } - - let first_revision = revisions.first().unwrap(); - let last_revision = revisions.last().unwrap(); - - let (base_rev_id, rev_id) = first_revision.pair_rev_id(); - let md5 = last_revision.md5.clone(); +struct GridRevisionCompactor(); +impl RevisionCompactor for GridRevisionCompactor { + fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { let delta = make_delta_from_revisions::(revisions)?; - let delta_data = delta.to_bytes(); - Ok(Revision::new(object_id, base_rev_id, rev_id, delta_data, user_id, md5)) + Ok(delta.to_bytes()) + } +} + +struct GridBlockMetaEditorManager { + editor_map: DashMap>, +} + +impl GridBlockMetaEditorManager { + fn new() -> Self { + Self { + editor_map: DashMap::new(), + } + } + + pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult { + // let ids = row_orders + // .items + // .into_iter() + // .map(|row_order| row_order.row_id) + // .collect::>(); + // let row_metas: Vec = self.kv_persistence.batch_get(ids)?; + // + // let make_cell = |field_id: String, raw_cell: CellMeta| { + // let some_field = self.field_map.get(&field_id); + // if some_field.is_none() { + // tracing::error!("Can't find the field with {}", field_id); + // return None; + // } + // self.cell_map.insert(raw_cell.id.clone(), raw_cell.clone()); + // + // let field = some_field.unwrap(); + // match stringify_deserialize(raw_cell.data, field.value()) { + // Ok(content) => { + // let cell = Cell { + // id: raw_cell.id, + // field_id: field_id.clone(), + // content, + // }; + // Some((field_id, cell)) + // } + // Err(_) => None, + // } + // }; + // + // let rows = row_metas + // .into_par_iter() + // .map(|row_meta| { + // let mut row = Row { + // id: row_meta.id.clone(), + // cell_by_field_id: Default::default(), + // height: row_meta.height, + // }; + // row.cell_by_field_id = row_meta + // .cell_by_field_id + // .into_par_iter() + // .flat_map(|(field_id, raw_cell)| make_cell(field_id, raw_cell)) + // .collect::>(); + // row + // }) + // .collect::>(); + // + // Ok(rows.into()) + todo!() } } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs new file mode 100644 index 0000000000..3e3e5e82d3 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs @@ -0,0 +1,125 @@ +use bytes::Bytes; +use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; +use flowy_collaboration::entities::revision::Revision; +use flowy_collaboration::util::make_delta_from_revisions; +use flowy_error::{FlowyError, FlowyResult}; +use flowy_grid_data_model::entities::RowMeta; +use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; +use lib_infra::future::FutureResult; +use lib_infra::uuid; +use lib_ot::core::PlainTextAttributes; +use std::sync::Arc; +use tokio::sync::RwLock; + +pub struct ClientGridBlockMetaEditor { + user_id: String, + block_id: String, + meta_pad: Arc>, + rev_manager: Arc, +} + +impl ClientGridBlockMetaEditor { + pub async fn new( + user_id: &str, + token: &str, + block_id: String, + mut rev_manager: RevisionManager, + ) -> FlowyResult { + let cloud = Arc::new(GridBlockMetaRevisionCloudService { + token: token.to_owned(), + }); + let block_meta_pad = rev_manager.load::(cloud).await?; + let meta_pad = Arc::new(RwLock::new(block_meta_pad)); + let rev_manager = Arc::new(rev_manager); + let user_id = user_id.to_owned(); + Ok(Self { + user_id, + block_id, + meta_pad, + rev_manager, + }) + } + + pub async fn create_empty_row(&self) -> FlowyResult<()> { + let row = RowMeta::new(&uuid(), &self.block_id, vec![]); + self.create_row(row).await?; + Ok(()) + } + + async fn create_row(&self, row: RowMeta) -> FlowyResult<()> { + // let _ = self.modify(|grid| Ok(grid.create_row(row)?)).await?; + // self.cell_map.insert(row.id.clone(), row.clone()); + // let _ = self.kv_persistence.set(row)?; + Ok(()) + } + + pub async fn delete_rows(&self, ids: Vec) -> FlowyResult<()> { + // let _ = self.modify(|grid| Ok(grid.delete_rows(&ids)?)).await?; + // let _ = self.kv.batch_delete(ids)?; + Ok(()) + } + + async fn modify(&self, f: F) -> FlowyResult<()> + where + F: for<'a> FnOnce(&'a mut GridBlockMetaPad) -> FlowyResult>, + { + let mut write_guard = self.meta_pad.write().await; + match f(&mut *write_guard)? { + None => {} + Some(change) => { + let _ = self.apply_change(change).await?; + } + } + Ok(()) + } + + async fn apply_change(&self, change: GridBlockMetaChange) -> FlowyResult<()> { + let GridBlockMetaChange { delta, md5 } = change; + let user_id = self.user_id.clone(); + let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); + let delta_data = delta.to_bytes(); + let revision = Revision::new( + &self.rev_manager.object_id, + base_rev_id, + rev_id, + delta_data, + &user_id, + md5, + ); + let _ = self + .rev_manager + .add_local_revision(&revision, Box::new(GridBlockMetaRevisionCompactor())) + .await?; + Ok(()) + } +} + +struct GridBlockMetaRevisionCloudService { + #[allow(dead_code)] + token: String, +} + +impl RevisionCloudService for GridBlockMetaRevisionCloudService { + #[tracing::instrument(level = "trace", skip(self))] + fn fetch_object(&self, _user_id: &str, _object_id: &str) -> FutureResult, FlowyError> { + FutureResult::new(async move { Ok(vec![]) }) + } +} + +struct GridBlockMetaPadBuilder(); +impl RevisionObjectBuilder for GridBlockMetaPadBuilder { + type Output = GridBlockMetaPad; + + fn build_object(object_id: &str, revisions: Vec) -> FlowyResult { + let pad = GridBlockMetaPad::from_revisions(object_id, revisions)?; + Ok(pad) + } +} + +struct GridBlockMetaRevisionCompactor(); +impl RevisionCompactor for GridBlockMetaRevisionCompactor { + fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { + let delta = make_delta_from_revisions::(revisions)?; + Ok(delta.to_bytes()) + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index f1e1086589..226426aeb7 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -3,5 +3,6 @@ mod util; pub mod cell_data; pub mod grid_builder; pub mod grid_editor; +pub mod grid_meta_editor; pub mod kv_persistence; pub mod stringify; diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs index 5550395229..6fea7bbe73 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs @@ -66,10 +66,10 @@ fn make_view_data_processor( ) -> ViewDataProcessorMap { let mut map: HashMap> = HashMap::new(); - let block_data_impl = BlockManagerViewDataImpl(text_block_manager); + let block_data_impl = TextBlockViewDataProcessor(text_block_manager); map.insert(block_data_impl.data_type(), Arc::new(block_data_impl)); - let grid_data_impl = GridManagerViewDataImpl(grid_manager); + let grid_data_impl = GridViewDataProcessor(grid_manager); map.insert(grid_data_impl.data_type(), Arc::new(grid_data_impl)); Arc::new(map) @@ -133,8 +133,8 @@ impl WSMessageReceiver for FolderWSMessageReceiverImpl { } } -struct BlockManagerViewDataImpl(Arc); -impl ViewDataProcessor for BlockManagerViewDataImpl { +struct TextBlockViewDataProcessor(Arc); +impl ViewDataProcessor for TextBlockViewDataProcessor { fn initialize(&self) -> FutureResult<(), FlowyError> { let manager = self.0.clone(); FutureResult::new(async move { manager.init() }) @@ -186,8 +186,8 @@ impl ViewDataProcessor for BlockManagerViewDataImpl { } } -struct GridManagerViewDataImpl(Arc); -impl ViewDataProcessor for GridManagerViewDataImpl { +struct GridViewDataProcessor(Arc); +impl ViewDataProcessor for GridViewDataProcessor { fn initialize(&self) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs new file mode 100644 index 0000000000..ba4a0950af --- /dev/null +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs @@ -0,0 +1,235 @@ +use crate::cache::disk::RevisionDiskCache; +use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; +use crate::memory::RevisionMemoryCacheDelegate; +use bytes::Bytes; +use diesel::{sql_types::Integer, update, SqliteConnection}; +use flowy_collaboration::{ + entities::revision::{RevId, RevType, Revision, RevisionRange}, + util::md5, +}; +use flowy_database::{ + impl_sql_integer_expression, insert_or_ignore_into, + prelude::*, + schema::{grid_meta_rev_table, grid_meta_rev_table::dsl}, + ConnectionPool, +}; +use flowy_error::{internal_error, FlowyError, FlowyResult}; +use std::sync::Arc; + +pub struct SQLiteGridBlockMetaRevisionPersistence { + user_id: String, + pub(crate) pool: Arc, +} + +impl RevisionDiskCache for SQLiteGridBlockMetaRevisionPersistence { + type Error = FlowyError; + + fn create_revision_records(&self, revision_records: Vec) -> Result<(), Self::Error> { + let conn = self.pool.get().map_err(internal_error)?; + let _ = GridMetaRevisionSql::create(revision_records, &*conn)?; + Ok(()) + } + + fn read_revision_records( + &self, + object_id: &str, + rev_ids: Option>, + ) -> Result, Self::Error> { + let conn = self.pool.get().map_err(internal_error)?; + let records = GridMetaRevisionSql::read(&self.user_id, object_id, rev_ids, &*conn)?; + Ok(records) + } + + fn read_revision_records_with_range( + &self, + object_id: &str, + range: &RevisionRange, + ) -> Result, Self::Error> { + let conn = &*self.pool.get().map_err(internal_error)?; + let revisions = GridMetaRevisionSql::read_with_range(&self.user_id, object_id, range.clone(), conn)?; + Ok(revisions) + } + + fn update_revision_record(&self, changesets: Vec) -> FlowyResult<()> { + let conn = &*self.pool.get().map_err(internal_error)?; + let _ = conn.immediate_transaction::<_, FlowyError, _>(|| { + for changeset in changesets { + let _ = GridMetaRevisionSql::update(changeset, conn)?; + } + Ok(()) + })?; + Ok(()) + } + + fn delete_revision_records(&self, object_id: &str, rev_ids: Option>) -> Result<(), Self::Error> { + let conn = &*self.pool.get().map_err(internal_error)?; + let _ = GridMetaRevisionSql::delete(object_id, rev_ids, conn)?; + Ok(()) + } + + fn delete_and_insert_records( + &self, + object_id: &str, + deleted_rev_ids: Option>, + inserted_records: Vec, + ) -> Result<(), Self::Error> { + let conn = self.pool.get().map_err(internal_error)?; + conn.immediate_transaction::<_, FlowyError, _>(|| { + let _ = GridMetaRevisionSql::delete(object_id, deleted_rev_ids, &*conn)?; + let _ = GridMetaRevisionSql::create(inserted_records, &*conn)?; + Ok(()) + }) + } +} + +impl SQLiteGridBlockMetaRevisionPersistence { + pub fn new(user_id: &str, pool: Arc) -> Self { + Self { + user_id: user_id.to_owned(), + pool, + } + } +} + +struct GridMetaRevisionSql(); +impl GridMetaRevisionSql { + fn create(revision_records: Vec, conn: &SqliteConnection) -> Result<(), FlowyError> { + // Batch insert: https://diesel.rs/guides/all-about-inserts.html + + let records = revision_records + .into_iter() + .map(|record| { + tracing::trace!( + "[GridMetaRevisionSql] create revision: {}:{:?}", + record.revision.object_id, + record.revision.rev_id + ); + let rev_state: GridMetaRevisionState = record.state.into(); + ( + dsl::object_id.eq(record.revision.object_id), + dsl::base_rev_id.eq(record.revision.base_rev_id), + dsl::rev_id.eq(record.revision.rev_id), + dsl::data.eq(record.revision.delta_data), + dsl::state.eq(rev_state), + ) + }) + .collect::>(); + + let _ = insert_or_ignore_into(dsl::grid_meta_rev_table) + .values(&records) + .execute(conn)?; + Ok(()) + } + + fn update(changeset: RevisionChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> { + let state: GridMetaRevisionState = changeset.state.clone().into(); + let filter = dsl::grid_meta_rev_table + .filter(dsl::rev_id.eq(changeset.rev_id.as_ref())) + .filter(dsl::object_id.eq(changeset.object_id)); + let _ = update(filter).set(dsl::state.eq(state)).execute(conn)?; + tracing::debug!( + "[GridMetaRevisionSql] update revision:{} state:to {:?}", + changeset.rev_id, + changeset.state + ); + Ok(()) + } + + fn read( + user_id: &str, + object_id: &str, + rev_ids: Option>, + conn: &SqliteConnection, + ) -> Result, FlowyError> { + let mut sql = dsl::grid_meta_rev_table + .filter(dsl::object_id.eq(object_id)) + .into_boxed(); + if let Some(rev_ids) = rev_ids { + sql = sql.filter(dsl::rev_id.eq_any(rev_ids)); + } + let rows = sql.order(dsl::rev_id.asc()).load::(conn)?; + let records = rows + .into_iter() + .map(|row| mk_revision_record_from_table(user_id, row)) + .collect::>(); + + Ok(records) + } + + fn read_with_range( + user_id: &str, + object_id: &str, + range: RevisionRange, + conn: &SqliteConnection, + ) -> Result, FlowyError> { + let rev_tables = dsl::grid_meta_rev_table + .filter(dsl::rev_id.ge(range.start)) + .filter(dsl::rev_id.le(range.end)) + .filter(dsl::object_id.eq(object_id)) + .order(dsl::rev_id.asc()) + .load::(conn)?; + + let revisions = rev_tables + .into_iter() + .map(|table| mk_revision_record_from_table(user_id, table)) + .collect::>(); + Ok(revisions) + } + + fn delete(object_id: &str, rev_ids: Option>, conn: &SqliteConnection) -> Result<(), FlowyError> { + let mut sql = diesel::delete(dsl::grid_meta_rev_table).into_boxed(); + sql = sql.filter(dsl::object_id.eq(object_id)); + + if let Some(rev_ids) = rev_ids { + tracing::trace!("[GridMetaRevisionSql] Delete revision: {}:{:?}", object_id, rev_ids); + sql = sql.filter(dsl::rev_id.eq_any(rev_ids)); + } + + let affected_row = sql.execute(conn)?; + tracing::trace!("[GridMetaRevisionSql] Delete {} rows", affected_row); + Ok(()) + } +} + +#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] +#[table_name = "grid_meta_rev_table"] +struct GridMetaRevisionTable { + id: i32, + object_id: String, + base_rev_id: i64, + rev_id: i64, + data: Vec, + state: GridMetaRevisionState, +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, FromSqlRow, AsExpression)] +#[repr(i32)] +#[sql_type = "Integer"] +pub enum GridMetaRevisionState { + Sync = 0, + Ack = 1, +} +impl_sql_integer_expression!(GridMetaRevisionState); +impl_rev_state_map!(GridMetaRevisionState); +impl std::default::Default for GridMetaRevisionState { + fn default() -> Self { + GridMetaRevisionState::Sync + } +} + +fn mk_revision_record_from_table(user_id: &str, table: GridMetaRevisionTable) -> RevisionRecord { + let md5 = md5(&table.data); + let revision = Revision::new( + &table.object_id, + table.base_rev_id, + table.rev_id, + Bytes::from(table.data), + user_id, + md5, + ); + RevisionRecord { + revision, + state: table.state.into(), + write_to_disk: false, + } +} diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs index 6053b17133..385bc812c7 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs @@ -1,5 +1,6 @@ use crate::cache::disk::RevisionDiskCache; use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; +use crate::memory::RevisionMemoryCacheDelegate; use bytes::Bytes; use diesel::{sql_types::Integer, update, SqliteConnection}; use flowy_collaboration::{ @@ -23,12 +24,9 @@ pub struct SQLiteGridRevisionPersistence { impl RevisionDiskCache for SQLiteGridRevisionPersistence { type Error = FlowyError; - fn create_revision_records( - &self, - revision_records: Vec, - conn: &SqliteConnection, - ) -> Result<(), Self::Error> { - let _ = GridRevisionSql::create(revision_records, conn)?; + fn create_revision_records(&self, revision_records: Vec) -> Result<(), Self::Error> { + let conn = self.pool.get().map_err(internal_error)?; + let _ = GridRevisionSql::create(revision_records, &*conn)?; Ok(()) } @@ -78,14 +76,14 @@ impl RevisionDiskCache for SQLiteGridRevisionPersistence { let conn = self.pool.get().map_err(internal_error)?; conn.immediate_transaction::<_, FlowyError, _>(|| { let _ = GridRevisionSql::delete(object_id, deleted_rev_ids, &*conn)?; - let _ = self.create_revision_records(inserted_records, &*conn)?; + let _ = GridRevisionSql::create(inserted_records, &*conn)?; Ok(()) }) } } impl SQLiteGridRevisionPersistence { - pub(crate) fn new(user_id: &str, pool: Arc) -> Self { + pub fn new(user_id: &str, pool: Arc) -> Self { Self { user_id: user_id.to_owned(), pool, @@ -193,13 +191,13 @@ impl GridRevisionSql { #[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] #[table_name = "grid_rev_table"] -pub(crate) struct GridRevisionTable { +struct GridRevisionTable { id: i32, - pub(crate) object_id: String, - pub(crate) base_rev_id: i64, - pub(crate) rev_id: i64, - pub(crate) data: Vec, - pub(crate) state: GridRevisionState, + object_id: String, + base_rev_id: i64, + rev_id: i64, + data: Vec, + state: GridRevisionState, } #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, FromSqlRow, AsExpression)] @@ -209,6 +207,8 @@ pub enum GridRevisionState { Sync = 0, Ack = 1, } +impl_sql_integer_expression!(GridRevisionState); +impl_rev_state_map!(GridRevisionState); impl std::default::Default for GridRevisionState { fn default() -> Self { @@ -216,44 +216,6 @@ impl std::default::Default for GridRevisionState { } } -impl std::convert::From for GridRevisionState { - fn from(value: i32) -> Self { - match value { - 0 => GridRevisionState::Sync, - 1 => GridRevisionState::Ack, - o => { - tracing::error!("Unsupported rev state {}, fallback to RevState::Local", o); - GridRevisionState::Sync - } - } - } -} - -impl GridRevisionState { - pub fn value(&self) -> i32 { - *self as i32 - } -} -impl_sql_integer_expression!(GridRevisionState); - -impl std::convert::From for RevisionState { - fn from(s: GridRevisionState) -> Self { - match s { - GridRevisionState::Sync => RevisionState::Sync, - GridRevisionState::Ack => RevisionState::Ack, - } - } -} - -impl std::convert::From for GridRevisionState { - fn from(s: RevisionState) -> Self { - match s { - RevisionState::Sync => GridRevisionState::Sync, - RevisionState::Ack => GridRevisionState::Ack, - } - } -} - fn mk_revision_record_from_table(user_id: &str, table: GridRevisionTable) -> RevisionRecord { let md5 = md5(&table.data); let revision = Revision::new( diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs index 4fcad2d2ec..e261f8d7ec 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs @@ -1,11 +1,14 @@ mod folder_rev_impl; +mod grid_meta_rev_impl; mod grid_rev_impl; mod text_rev_impl; pub use folder_rev_impl::*; +pub use grid_meta_rev_impl::*; pub use grid_rev_impl::*; pub use text_rev_impl::*; +use crate::memory::RevisionMemoryCacheDelegate; use diesel::SqliteConnection; use flowy_collaboration::entities::revision::{RevId, Revision, RevisionRange}; use flowy_error::FlowyResult; @@ -13,11 +16,7 @@ use std::fmt::Debug; pub trait RevisionDiskCache: Sync + Send { type Error: Debug; - fn create_revision_records( - &self, - revision_records: Vec, - conn: &SqliteConnection, - ) -> Result<(), Self::Error>; + fn create_revision_records(&self, revision_records: Vec) -> Result<(), Self::Error>; // Read all the records if the rev_ids is None fn read_revision_records( diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs index 7659ad33dc..0d780f824a 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs @@ -1,5 +1,6 @@ use crate::cache::disk::RevisionDiskCache; use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; +use crate::memory::RevisionMemoryCacheDelegate; use bytes::Bytes; use diesel::{sql_types::Integer, update, SqliteConnection}; use flowy_collaboration::{ @@ -23,12 +24,9 @@ pub struct SQLiteTextBlockRevisionPersistence { impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { type Error = FlowyError; - fn create_revision_records( - &self, - revision_records: Vec, - conn: &SqliteConnection, - ) -> Result<(), Self::Error> { - let _ = TextRevisionSql::create(revision_records, conn)?; + fn create_revision_records(&self, revision_records: Vec) -> Result<(), Self::Error> { + let conn = self.pool.get().map_err(internal_error)?; + let _ = TextRevisionSql::create(revision_records, &*conn)?; Ok(()) } @@ -78,14 +76,14 @@ impl RevisionDiskCache for SQLiteTextBlockRevisionPersistence { let conn = self.pool.get().map_err(internal_error)?; conn.immediate_transaction::<_, FlowyError, _>(|| { let _ = TextRevisionSql::delete(object_id, deleted_rev_ids, &*conn)?; - let _ = self.create_revision_records(inserted_records, &*conn)?; + let _ = TextRevisionSql::create(inserted_records, &*conn)?; Ok(()) }) } } impl SQLiteTextBlockRevisionPersistence { - pub(crate) fn new(user_id: &str, pool: Arc) -> Self { + pub fn new(user_id: &str, pool: Arc) -> Self { Self { user_id: user_id.to_owned(), pool, @@ -210,6 +208,8 @@ enum TextRevisionState { Sync = 0, Ack = 1, } +impl_sql_integer_expression!(TextRevisionState); +impl_rev_state_map!(TextRevisionState); impl std::default::Default for TextRevisionState { fn default() -> Self { @@ -217,44 +217,6 @@ impl std::default::Default for TextRevisionState { } } -impl std::convert::From for TextRevisionState { - fn from(value: i32) -> Self { - match value { - 0 => TextRevisionState::Sync, - 1 => TextRevisionState::Ack, - o => { - tracing::error!("Unsupported rev state {}, fallback to RevState::Local", o); - TextRevisionState::Sync - } - } - } -} - -impl TextRevisionState { - pub fn value(&self) -> i32 { - *self as i32 - } -} -impl_sql_integer_expression!(TextRevisionState); - -impl std::convert::From for RevisionState { - fn from(s: TextRevisionState) -> Self { - match s { - TextRevisionState::Sync => RevisionState::Sync, - TextRevisionState::Ack => RevisionState::Ack, - } - } -} - -impl std::convert::From for TextRevisionState { - fn from(s: RevisionState) -> Self { - match s { - RevisionState::Sync => TextRevisionState::Sync, - RevisionState::Ack => TextRevisionState::Ack, - } - } -} - fn mk_revision_record_from_table(user_id: &str, table: RevisionTable) -> RevisionRecord { let md5 = md5(&table.data); let revision = Revision::new( @@ -279,6 +241,7 @@ pub enum RevTableType { Local = 0, Remote = 1, } +impl_sql_integer_expression!(RevTableType); impl std::default::Default for RevTableType { fn default() -> Self { @@ -298,12 +261,6 @@ impl std::convert::From for RevTableType { } } } -impl RevTableType { - pub fn value(&self) -> i32 { - *self as i32 - } -} -impl_sql_integer_expression!(RevTableType); impl std::convert::From for RevTableType { fn from(ty: RevType) -> Self { diff --git a/frontend/rust-lib/flowy-sync/src/rev_manager.rs b/frontend/rust-lib/flowy-sync/src/rev_manager.rs index ab5d7858b3..ae26bbf68c 100644 --- a/frontend/rust-lib/flowy-sync/src/rev_manager.rs +++ b/frontend/rust-lib/flowy-sync/src/rev_manager.rs @@ -1,11 +1,13 @@ use crate::disk::RevisionState; use crate::{RevisionPersistence, WSDataProviderDataSource}; +use bytes::Bytes; use flowy_collaboration::{ entities::revision::{RepeatedRevision, Revision, RevisionRange}, util::{pair_rev_id_from_revisions, RevIdCounter}, }; use flowy_error::{FlowyError, FlowyResult}; use lib_infra::future::FutureResult; +use lib_ot::core::{Attributes, Delta}; use std::sync::Arc; pub trait RevisionCloudService: Send + Sync { @@ -17,8 +19,26 @@ pub trait RevisionObjectBuilder: Send + Sync { fn build_object(object_id: &str, revisions: Vec) -> FlowyResult; } -pub trait RevisionCompact: Send + Sync { - fn compact_revisions(user_id: &str, object_id: &str, revisions: Vec) -> FlowyResult; +pub trait RevisionCompactor: Send + Sync { + fn compact(&self, user_id: &str, object_id: &str, mut revisions: Vec) -> FlowyResult { + if revisions.is_empty() { + return Err(FlowyError::internal().context("Can't compact the empty folder's revisions")); + } + + if revisions.len() == 1 { + return Ok(revisions.pop().unwrap()); + } + + let first_revision = revisions.first().unwrap(); + let last_revision = revisions.last().unwrap(); + + let (base_rev_id, rev_id) = first_revision.pair_rev_id(); + let md5 = last_revision.md5.clone(); + let delta_data = self.bytes_from_revisions(revisions)?; + Ok(Revision::new(object_id, base_rev_id, rev_id, delta_data, user_id, md5)) + } + + fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult; } pub struct RevisionManager { @@ -48,10 +68,9 @@ impl RevisionManager { } } - pub async fn load(&mut self, cloud: Arc) -> FlowyResult + pub async fn load(&mut self, cloud: Arc) -> FlowyResult where B: RevisionObjectBuilder, - C: RevisionCompact, { let (revisions, rev_id) = RevisionLoader { object_id: self.object_id.clone(), @@ -84,15 +103,16 @@ impl RevisionManager { Ok(()) } - #[tracing::instrument(level = "debug", skip(self, revision))] - pub async fn add_local_revision(&self, revision: &Revision) -> Result<(), FlowyError> - where - C: RevisionCompact, - { + #[tracing::instrument(level = "debug", skip_all, err)] + pub async fn add_local_revision<'a>( + &'a self, + revision: &Revision, + compactor: Box, + ) -> Result<(), FlowyError> { if revision.delta_data.is_empty() { return Err(FlowyError::internal().context("Delta data should be empty")); } - let rev_id = self.rev_persistence.add_sync_revision::(revision).await?; + let rev_id = self.rev_persistence.add_sync_revision(revision, compactor).await?; self.rev_id_counter.set(rev_id); Ok(()) } diff --git a/frontend/rust-lib/flowy-sync/src/rev_persistence.rs b/frontend/rust-lib/flowy-sync/src/rev_persistence.rs index d6b129170f..8a1d9647c4 100644 --- a/frontend/rust-lib/flowy-sync/src/rev_persistence.rs +++ b/frontend/rust-lib/flowy-sync/src/rev_persistence.rs @@ -1,9 +1,10 @@ use crate::cache::{ disk::{RevisionChangeset, RevisionDiskCache, SQLiteTextBlockRevisionPersistence}, - memory::{RevisionMemoryCache, RevisionMemoryCacheDelegate}, + memory::RevisionMemoryCacheDelegate, }; use crate::disk::{RevisionRecord, RevisionState}; -use crate::RevisionCompact; +use crate::memory::RevisionMemoryCache; +use crate::RevisionCompactor; use flowy_collaboration::entities::revision::{Revision, RevisionRange}; use flowy_database::ConnectionPool; use flowy_error::{internal_error, FlowyError, FlowyResult}; @@ -21,13 +22,17 @@ pub struct RevisionPersistence { memory_cache: Arc, sync_seq: RwLock, } + impl RevisionPersistence { - pub fn new(user_id: &str, object_id: &str, pool: Arc) -> RevisionPersistence { - let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(user_id, pool)); - let memory_cache = Arc::new(RevisionMemoryCache::new(object_id, Arc::new(disk_cache.clone()))); + pub fn new( + user_id: &str, + object_id: &str, + disk_cache: Arc>, + ) -> RevisionPersistence { let object_id = object_id.to_owned(); let user_id = user_id.to_owned(); let sync_seq = RwLock::new(RevisionSyncSequence::new()); + let memory_cache = Arc::new(RevisionMemoryCache::new(&object_id, Arc::new(disk_cache.clone()))); Self { user_id, object_id, @@ -54,11 +59,12 @@ impl RevisionPersistence { } /// Save the revision to disk and append it to the end of the sync sequence. - #[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, compact_range, object_id=%self.object_id), err)] - pub(crate) async fn add_sync_revision(&self, revision: &Revision) -> FlowyResult - where - C: RevisionCompact, - { + #[tracing::instrument(level = "trace", skip_all, fields(rev_id, compact_range, object_id=%self.object_id), err)] + pub(crate) async fn add_sync_revision<'a>( + &'a self, + revision: &'a Revision, + compactor: Box, + ) -> FlowyResult { let result = self.sync_seq.read().await.compact(); match result { None => { @@ -78,7 +84,7 @@ impl RevisionPersistence { revisions.push(revision.clone()); // compact multiple revisions into one - let compact_revision = C::compact_revisions(&self.user_id, &self.object_id, revisions)?; + let compact_revision = compactor.compact(&self.user_id, &self.object_id, revisions)?; let rev_id = compact_revision.rev_id; tracing::Span::current().record("rev_id", &rev_id); @@ -215,17 +221,15 @@ pub fn mk_revision_disk_cache( Arc::new(SQLiteTextBlockRevisionPersistence::new(user_id, pool)) } -impl RevisionMemoryCacheDelegate for Arc { - #[tracing::instrument(level = "trace", skip(self, records), fields(checkpoint_result), err)] +impl RevisionMemoryCacheDelegate for Arc> { fn checkpoint_tick(&self, mut records: Vec) -> FlowyResult<()> { - let conn = &*self.pool.get().map_err(internal_error)?; records.retain(|record| record.write_to_disk); if !records.is_empty() { tracing::Span::current().record( "checkpoint_result", &format!("{} records were saved", records.len()).as_str(), ); - let _ = self.create_revision_records(records, conn)?; + let _ = self.create_revision_records(records)?; } Ok(()) } diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index 54f4b67967..0ca0d5ee03 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -1,28 +1,28 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{BlockMeta, RowMeta, RowMetaChangeset, RowOrder}; +use flowy_grid_data_model::entities::{GridBlockMeta, RowMeta, RowMetaChangeset, RowOrder}; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use serde::{Deserialize, Serialize}; use std::sync::Arc; -pub type BlockMetaDelta = PlainTextDelta; -pub type BlockDeltaBuilder = PlainTextDeltaBuilder; +pub type GridBlockMetaDelta = PlainTextDelta; +pub type GridBlockMetaDeltaBuilder = PlainTextDeltaBuilder; #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct BlockMetaPad { +pub struct GridBlockMetaPad { block_id: String, rows: Vec>, #[serde(skip)] - pub(crate) delta: BlockMetaDelta, + pub(crate) delta: GridBlockMetaDelta, } -impl BlockMetaPad { - pub fn from_delta(delta: BlockMetaDelta) -> CollaborateResult { +impl GridBlockMetaPad { + pub fn from_delta(delta: GridBlockMetaDelta) -> CollaborateResult { let s = delta.to_str()?; - let block_meta: BlockMeta = serde_json::from_str(&s).map_err(|e| { + let block_meta: GridBlockMeta = serde_json::from_str(&s).map_err(|e| { CollaborateError::internal().context(format!("Deserialize delta to block meta failed: {}", e)) })?; let block_id = block_meta.block_id; @@ -31,25 +31,25 @@ impl BlockMetaPad { } pub fn from_revisions(_grid_id: &str, revisions: Vec) -> CollaborateResult { - let block_delta: BlockMetaDelta = make_delta_from_revisions::(revisions)?; + let block_delta: GridBlockMetaDelta = make_delta_from_revisions::(revisions)?; Self::from_delta(block_delta) } - pub fn add_row(&mut self, row: RowMeta) -> CollaborateResult> { + pub fn add_row(&mut self, row: RowMeta) -> CollaborateResult> { self.modify(|rows| { rows.push(Arc::new(row)); Ok(Some(())) }) } - pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { + pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { self.modify(|rows| { rows.retain(|row| !row_ids.contains(&row.id)); Ok(Some(())) }) } - pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { + pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { let row_id = changeset.row_id.clone(); self.modify_row(&row_id, |row| { let mut is_changed = None; @@ -74,7 +74,7 @@ impl BlockMetaPad { }) } - pub fn modify(&mut self, f: F) -> CollaborateResult> + pub fn modify(&mut self, f: F) -> CollaborateResult> where F: for<'a> FnOnce(&'a mut Vec>) -> CollaborateResult>, { @@ -88,14 +88,14 @@ impl BlockMetaPad { None => Ok(None), Some(delta) => { self.delta = self.delta.compose(&delta)?; - Ok(Some(BlockMetaChange { delta, md5: self.md5() })) + Ok(Some(GridBlockMetaChange { delta, md5: self.md5() })) } } } } } - fn modify_row(&mut self, row_id: &str, f: F) -> CollaborateResult> + fn modify_row(&mut self, row_id: &str, f: F) -> CollaborateResult> where F: FnOnce(&mut RowMeta) -> CollaborateResult>, { @@ -123,39 +123,39 @@ impl BlockMetaPad { } } -fn json_from_grid(block_meta: &Arc) -> CollaborateResult { +fn json_from_grid(block_meta: &Arc) -> CollaborateResult { let json = serde_json::to_string(block_meta) .map_err(|err| internal_error(format!("Serialize grid to json str failed. {:?}", err)))?; Ok(json) } -pub struct BlockMetaChange { - pub delta: BlockMetaDelta, +pub struct GridBlockMetaChange { + pub delta: GridBlockMetaDelta, /// md5: the md5 of the grid after applying the change. pub md5: String, } -pub fn make_block_meta_delta(block_meta: &BlockMeta) -> BlockMetaDelta { +pub fn make_block_meta_delta(block_meta: &GridBlockMeta) -> GridBlockMetaDelta { let json = serde_json::to_string(&block_meta).unwrap(); PlainTextDeltaBuilder::new().insert(&json).build() } -pub fn make_block_meta_revisions(user_id: &str, block_meta: &BlockMeta) -> RepeatedRevision { +pub fn make_block_meta_revisions(user_id: &str, block_meta: &GridBlockMeta) -> RepeatedRevision { let delta = make_block_meta_delta(block_meta); let bytes = delta.to_bytes(); let revision = Revision::initial_revision(user_id, &block_meta.block_id, bytes); revision.into() } -impl std::default::Default for BlockMetaPad { +impl std::default::Default for GridBlockMetaPad { fn default() -> Self { - let block_meta = BlockMeta { + let block_meta = GridBlockMeta { block_id: uuid(), rows: vec![], }; let delta = make_block_meta_delta(&block_meta); - BlockMetaPad { + GridBlockMetaPad { block_id: block_meta.block_id, rows: block_meta.rows.into_iter().map(Arc::new).collect::>(), delta, @@ -165,7 +165,7 @@ impl std::default::Default for BlockMetaPad { #[cfg(test)] mod tests { - use crate::client_grid::{BlockMetaDelta, BlockMetaPad}; + use crate::client_grid::{GridBlockMetaDelta, GridMetaPad}; use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset}; use std::str::FromStr; @@ -241,8 +241,8 @@ mod tests { ); } - fn test_pad() -> BlockMetaPad { - let delta = BlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap(); - BlockMetaPad::from_delta(delta).unwrap() + fn test_pad() -> GridMetaPad { + let delta = GridBlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap(); + GridMetaPad::from_delta(delta).unwrap() } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index f61cd484fc..6e04107e44 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -1,9 +1,13 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{Field, FieldOrder, Grid, GridMeta, RowMeta, RowOrder}; +use flowy_grid_data_model::entities::{ + Field, FieldChangeset, FieldOrder, Grid, GridBlock, GridBlockChangeset, GridMeta, RepeatedField, + RepeatedFieldOrder, RowMeta, RowOrder, +}; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; +use std::collections::HashMap; use std::sync::Arc; pub type GridDelta = PlainTextDelta; @@ -31,13 +35,6 @@ impl GridMetaPad { Self::from_delta(grid_delta) } - pub fn create_row(&mut self, row: RowMeta) -> CollaborateResult> { - self.modify_grid(|grid| { - // grid.rows.push(row); - Ok(Some(())) - }) - } - pub fn create_field(&mut self, field: Field) -> CollaborateResult> { self.modify_grid(|grid| { grid.fields.push(field); @@ -45,13 +42,6 @@ impl GridMetaPad { }) } - pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { - self.modify_grid(|grid| { - // grid.rows.retain(|row| !row_ids.contains(&row.id)); - Ok(Some(())) - }) - } - pub fn delete_field(&mut self, field_id: &str) -> CollaborateResult> { self.modify_grid(|grid| match grid.fields.iter().position(|field| field.id == field_id) { None => Ok(None), @@ -62,30 +52,93 @@ impl GridMetaPad { }) } - pub fn md5(&self) -> String { - md5(&self.delta.to_bytes()) - } - - pub fn grid_data(&self) -> Grid { - let field_orders = self + pub fn get_fields(&self, field_orders: RepeatedFieldOrder) -> CollaborateResult { + let field_by_field_id = self .grid_meta .fields .iter() - .map(FieldOrder::from) - .collect::>(); + .map(|field| (&field.id, field)) + .collect::>(); - // let row_orders = self - // .grid_meta - // .rows - // .iter() - // .map(RowOrder::from) - // .collect::>(); + let fields = field_orders + .iter() + .flat_map(|field_order| match field_by_field_id.get(&field_order.field_id) { + None => { + tracing::error!("Can't find the field with {}", field_order.field_id); + None + } + Some(field) => Some((*field).clone()), + }) + .collect::>(); + Ok(fields.into()) + } - Grid { - id: "".to_string(), - field_orders, - row_orders: vec![], - } + pub fn update_field(&mut self, change: FieldChangeset) -> CollaborateResult> { + let field_id = change.field_id.clone(); + self.modify_field(&field_id, |field| { + let mut is_changed = None; + if let Some(name) = change.name { + field.name = name; + is_changed = Some(()) + } + + if let Some(desc) = change.desc { + field.desc = desc; + is_changed = Some(()) + } + + if let Some(field_type) = change.field_type { + field.field_type = field_type; + is_changed = Some(()) + } + + if let Some(frozen) = change.frozen { + field.frozen = frozen; + is_changed = Some(()) + } + + if let Some(visibility) = change.visibility { + field.visibility = visibility; + is_changed = Some(()) + } + + if let Some(width) = change.width { + field.width = width; + is_changed = Some(()) + } + + if let Some(type_options) = change.type_options { + field.type_options = type_options; + is_changed = Some(()) + } + + Ok(is_changed) + }) + } + + pub fn create_block(&mut self, block: GridBlock) -> CollaborateResult> { + self.modify_grid(|grid| { + grid.blocks.push(block); + Ok(Some(())) + }) + } + + pub fn update_block(&mut self, change: GridBlockChangeset) -> CollaborateResult> { + let block_id = change.block_id.clone(); + self.modify_block(&block_id, |block| { + let mut is_changed = None; + + if let Some(row_count) = change.row_count { + block.row_count = row_count; + is_changed = Some(()); + } + + Ok(is_changed) + }) + } + + pub fn md5(&self) -> String { + md5(&self.delta.to_bytes()) } pub fn delta_str(&self) -> String { @@ -96,7 +149,7 @@ impl GridMetaPad { &self.grid_meta.fields } - pub fn modify_grid(&mut self, f: F) -> CollaborateResult> + fn modify_grid(&mut self, f: F) -> CollaborateResult> where F: FnOnce(&mut GridMeta) -> CollaborateResult>, { @@ -116,6 +169,32 @@ impl GridMetaPad { } } } + + pub fn modify_block(&mut self, block_id: &str, f: F) -> CollaborateResult> + where + F: FnOnce(&mut GridBlock) -> CollaborateResult>, + { + self.modify_grid(|grid| match grid.blocks.iter().position(|block| block.id == block_id) { + None => { + tracing::warn!("[GridMetaPad]: Can't find any block with id: {}", block_id); + Ok(None) + } + Some(index) => f(&mut grid.blocks[index]), + }) + } + + pub fn modify_field(&mut self, field_id: &str, f: F) -> CollaborateResult> + where + F: FnOnce(&mut Field) -> CollaborateResult>, + { + self.modify_grid(|grid| match grid.fields.iter().position(|field| field.id == field_id) { + None => { + tracing::warn!("[GridMetaPad]: Can't find any field with id: {}", field_id); + Ok(None) + } + Some(index) => f(&mut grid.fields[index]), + }) + } } fn json_from_grid(grid: &Arc) -> CollaborateResult { 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 e5f5c189cc..00c3981d79 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -2,9 +2,6 @@ use crate::entities::{Field, RowMeta}; use flowy_derive::ProtoBuf; use std::collections::HashMap; -pub const DEFAULT_ROW_HEIGHT: i32 = 36; -pub const DEFAULT_FIELD_WIDTH: i32 = 150; - #[derive(Debug, Clone, Default, ProtoBuf)] pub struct Grid { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index e8483dcb02..f6691456c8 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -15,11 +15,11 @@ pub struct GridMeta { pub fields: Vec, #[pb(index = 3)] - pub blocks: Vec, + pub blocks: Vec, } #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] -pub struct Block { +pub struct GridBlock { #[pb(index = 1)] pub id: String, @@ -30,8 +30,14 @@ pub struct Block { pub row_count: i32, } +pub struct GridBlockChangeset { + pub block_id: String, + pub start_row_index: Option, + pub row_count: Option, +} + #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] -pub struct BlockMeta { +pub struct GridBlockMeta { #[pb(index = 1)] pub block_id: String, @@ -81,6 +87,33 @@ impl Field { } } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct FieldChangeset { + #[pb(index = 1)] + pub field_id: String, + + #[pb(index = 2, one_of)] + pub name: Option, + + #[pb(index = 3, one_of)] + pub desc: Option, + + #[pb(index = 4, one_of)] + pub field_type: Option, + + #[pb(index = 5, one_of)] + pub frozen: Option, + + #[pb(index = 6, one_of)] + pub visibility: Option, + + #[pb(index = 7, one_of)] + pub width: Option, + + #[pb(index = 8, one_of)] + pub type_options: Option, +} + #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedField { #[pb(index = 1)] @@ -191,7 +224,7 @@ pub struct RowMeta { } impl RowMeta { - pub fn new(id: &str, grid_id: &str, cells: Vec) -> Self { + pub fn new(id: &str, block_id: &str, cells: Vec) -> Self { let cell_by_field_id = cells .into_iter() .map(|cell| (cell.id.clone(), cell)) @@ -199,7 +232,7 @@ impl RowMeta { Self { id: id.to_owned(), - block_id: grid_id.to_owned(), + block_id: block_id.to_owned(), cell_by_field_id, height: DEFAULT_ROW_HEIGHT, visibility: true, diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index 4107603b67..4ef31470a8 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -28,7 +28,7 @@ pub struct GridMeta { // message fields pub grid_id: ::std::string::String, pub fields: ::protobuf::RepeatedField, - pub blocks: ::protobuf::RepeatedField, + pub blocks: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -96,10 +96,10 @@ impl GridMeta { ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new()) } - // repeated .Block blocks = 3; + // repeated .GridBlock blocks = 3; - pub fn get_blocks(&self) -> &[Block] { + pub fn get_blocks(&self) -> &[GridBlock] { &self.blocks } pub fn clear_blocks(&mut self) { @@ -107,17 +107,17 @@ impl GridMeta { } // Param is passed by value, moved - pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { + pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { self.blocks = v; } // Mutable pointer to the field. - pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { + pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { &mut self.blocks } // Take field - pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { + pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) } } @@ -240,7 +240,7 @@ impl ::protobuf::Message for GridMeta { |m: &GridMeta| { &m.fields }, |m: &mut GridMeta| { &mut m.fields }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "blocks", |m: &GridMeta| { &m.blocks }, |m: &mut GridMeta| { &mut m.blocks }, @@ -281,7 +281,7 @@ impl ::protobuf::reflect::ProtobufValue for GridMeta { } #[derive(PartialEq,Clone,Default)] -pub struct Block { +pub struct GridBlock { // message fields pub id: ::std::string::String, pub start_row_index: i32, @@ -291,14 +291,14 @@ pub struct Block { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a Block { - fn default() -> &'a Block { - ::default_instance() +impl<'a> ::std::default::Default for &'a GridBlock { + fn default() -> &'a GridBlock { + ::default_instance() } } -impl Block { - pub fn new() -> Block { +impl GridBlock { + pub fn new() -> GridBlock { ::std::default::Default::default() } @@ -359,7 +359,7 @@ impl Block { } } -impl ::protobuf::Message for Block { +impl ::protobuf::Message for GridBlock { fn is_initialized(&self) -> bool { true } @@ -451,8 +451,8 @@ impl ::protobuf::Message for Block { Self::descriptor_static() } - fn new() -> Block { - Block::new() + fn new() -> GridBlock { + GridBlock::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -461,34 +461,34 @@ impl ::protobuf::Message for Block { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "id", - |m: &Block| { &m.id }, - |m: &mut Block| { &mut m.id }, + |m: &GridBlock| { &m.id }, + |m: &mut GridBlock| { &mut m.id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( "start_row_index", - |m: &Block| { &m.start_row_index }, - |m: &mut Block| { &mut m.start_row_index }, + |m: &GridBlock| { &m.start_row_index }, + |m: &mut GridBlock| { &mut m.start_row_index }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( "row_count", - |m: &Block| { &m.row_count }, - |m: &mut Block| { &mut m.row_count }, + |m: &GridBlock| { &m.row_count }, + |m: &mut GridBlock| { &mut m.row_count }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "Block", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlock", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static Block { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(Block::new) + fn default_instance() -> &'static GridBlock { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlock::new) } } -impl ::protobuf::Clear for Block { +impl ::protobuf::Clear for GridBlock { fn clear(&mut self) { self.id.clear(); self.start_row_index = 0; @@ -497,20 +497,20 @@ impl ::protobuf::Clear for Block { } } -impl ::std::fmt::Debug for Block { +impl ::std::fmt::Debug for GridBlock { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for Block { +impl ::protobuf::reflect::ProtobufValue for GridBlock { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } #[derive(PartialEq,Clone,Default)] -pub struct BlockMeta { +pub struct GridBlockMeta { // message fields pub block_id: ::std::string::String, pub rows: ::protobuf::RepeatedField, @@ -519,14 +519,14 @@ pub struct BlockMeta { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a BlockMeta { - fn default() -> &'a BlockMeta { - ::default_instance() +impl<'a> ::std::default::Default for &'a GridBlockMeta { + fn default() -> &'a GridBlockMeta { + ::default_instance() } } -impl BlockMeta { - pub fn new() -> BlockMeta { +impl GridBlockMeta { + pub fn new() -> GridBlockMeta { ::std::default::Default::default() } @@ -582,7 +582,7 @@ impl BlockMeta { } } -impl ::protobuf::Message for BlockMeta { +impl ::protobuf::Message for GridBlockMeta { fn is_initialized(&self) -> bool { for v in &self.rows { if !v.is_initialized() { @@ -665,8 +665,8 @@ impl ::protobuf::Message for BlockMeta { Self::descriptor_static() } - fn new() -> BlockMeta { - BlockMeta::new() + fn new() -> GridBlockMeta { + GridBlockMeta::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -675,29 +675,29 @@ impl ::protobuf::Message for BlockMeta { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "block_id", - |m: &BlockMeta| { &m.block_id }, - |m: &mut BlockMeta| { &mut m.block_id }, + |m: &GridBlockMeta| { &m.block_id }, + |m: &mut GridBlockMeta| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "rows", - |m: &BlockMeta| { &m.rows }, - |m: &mut BlockMeta| { &mut m.rows }, + |m: &GridBlockMeta| { &m.rows }, + |m: &mut GridBlockMeta| { &mut m.rows }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "BlockMeta", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlockMeta", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static BlockMeta { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(BlockMeta::new) + fn default_instance() -> &'static GridBlockMeta { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlockMeta::new) } } -impl ::protobuf::Clear for BlockMeta { +impl ::protobuf::Clear for GridBlockMeta { fn clear(&mut self) { self.block_id.clear(); self.rows.clear(); @@ -705,13 +705,13 @@ impl ::protobuf::Clear for BlockMeta { } } -impl ::std::fmt::Debug for BlockMeta { +impl ::std::fmt::Debug for GridBlockMeta { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for BlockMeta { +impl ::protobuf::reflect::ProtobufValue for GridBlockMeta { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -1319,6 +1319,645 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedField { } } +#[derive(PartialEq,Clone,Default)] +pub struct FieldChangeset { + // message fields + pub field_id: ::std::string::String, + // message oneof groups + pub one_of_name: ::std::option::Option, + pub one_of_desc: ::std::option::Option, + pub one_of_field_type: ::std::option::Option, + pub one_of_frozen: ::std::option::Option, + pub one_of_visibility: ::std::option::Option, + pub one_of_width: ::std::option::Option, + pub one_of_type_options: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a FieldChangeset { + fn default() -> &'a FieldChangeset { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangeset_oneof_one_of_name { + name(::std::string::String), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangeset_oneof_one_of_desc { + desc(::std::string::String), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangeset_oneof_one_of_field_type { + field_type(FieldType), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangeset_oneof_one_of_frozen { + frozen(bool), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangeset_oneof_one_of_visibility { + visibility(bool), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangeset_oneof_one_of_width { + width(i32), +} + +#[derive(Clone,PartialEq,Debug)] +pub enum FieldChangeset_oneof_one_of_type_options { + type_options(AnyData), +} + +impl FieldChangeset { + pub fn new() -> FieldChangeset { + ::std::default::Default::default() + } + + // string field_id = 1; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // string name = 2; + + + pub fn get_name(&self) -> &str { + match self.one_of_name { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(ref v)) => v, + _ => "", + } + } + pub fn clear_name(&mut self) { + self.one_of_name = ::std::option::Option::None; + } + + pub fn has_name(&self) -> bool { + match self.one_of_name { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.one_of_name = ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(v)) + } + + // Mutable pointer to the field. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(_)) = self.one_of_name { + } else { + self.one_of_name = ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(::std::string::String::new())); + } + match self.one_of_name { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + if self.has_name() { + match self.one_of_name.take() { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } + + // string desc = 3; + + + pub fn get_desc(&self) -> &str { + match self.one_of_desc { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(ref v)) => v, + _ => "", + } + } + pub fn clear_desc(&mut self) { + self.one_of_desc = ::std::option::Option::None; + } + + pub fn has_desc(&self) -> bool { + match self.one_of_desc { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_desc(&mut self, v: ::std::string::String) { + self.one_of_desc = ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(v)) + } + + // Mutable pointer to the field. + pub fn mut_desc(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(_)) = self.one_of_desc { + } else { + self.one_of_desc = ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(::std::string::String::new())); + } + match self.one_of_desc { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_desc(&mut self) -> ::std::string::String { + if self.has_desc() { + match self.one_of_desc.take() { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } + + // .FieldType field_type = 4; + + + pub fn get_field_type(&self) -> FieldType { + match self.one_of_field_type { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_field_type::field_type(v)) => v, + _ => FieldType::RichText, + } + } + pub fn clear_field_type(&mut self) { + self.one_of_field_type = ::std::option::Option::None; + } + + pub fn has_field_type(&self) -> bool { + match self.one_of_field_type { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_field_type::field_type(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_field_type(&mut self, v: FieldType) { + self.one_of_field_type = ::std::option::Option::Some(FieldChangeset_oneof_one_of_field_type::field_type(v)) + } + + // bool frozen = 5; + + + pub fn get_frozen(&self) -> bool { + match self.one_of_frozen { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_frozen::frozen(v)) => v, + _ => false, + } + } + pub fn clear_frozen(&mut self) { + self.one_of_frozen = ::std::option::Option::None; + } + + pub fn has_frozen(&self) -> bool { + match self.one_of_frozen { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_frozen::frozen(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_frozen(&mut self, v: bool) { + self.one_of_frozen = ::std::option::Option::Some(FieldChangeset_oneof_one_of_frozen::frozen(v)) + } + + // bool visibility = 6; + + + pub fn get_visibility(&self) -> bool { + match self.one_of_visibility { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_visibility::visibility(v)) => v, + _ => false, + } + } + pub fn clear_visibility(&mut self) { + self.one_of_visibility = ::std::option::Option::None; + } + + pub fn has_visibility(&self) -> bool { + match self.one_of_visibility { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_visibility::visibility(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_visibility(&mut self, v: bool) { + self.one_of_visibility = ::std::option::Option::Some(FieldChangeset_oneof_one_of_visibility::visibility(v)) + } + + // int32 width = 7; + + + pub fn get_width(&self) -> i32 { + match self.one_of_width { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(v)) => v, + _ => 0, + } + } + pub fn clear_width(&mut self) { + self.one_of_width = ::std::option::Option::None; + } + + pub fn has_width(&self) -> bool { + match self.one_of_width { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_width(&mut self, v: i32) { + self.one_of_width = ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(v)) + } + + // .AnyData type_options = 8; + + + pub fn get_type_options(&self) -> &AnyData { + match self.one_of_type_options { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(ref v)) => v, + _ => ::default_instance(), + } + } + pub fn clear_type_options(&mut self) { + self.one_of_type_options = ::std::option::Option::None; + } + + pub fn has_type_options(&self) -> bool { + match self.one_of_type_options { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_type_options(&mut self, v: AnyData) { + self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(v)) + } + + // Mutable pointer to the field. + pub fn mut_type_options(&mut self) -> &mut AnyData { + if let ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(_)) = self.one_of_type_options { + } else { + self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(AnyData::new())); + } + match self.one_of_type_options { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_type_options(&mut self) -> AnyData { + if self.has_type_options() { + match self.one_of_type_options.take() { + ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(v)) => v, + _ => panic!(), + } + } else { + AnyData::new() + } + } +} + +impl ::protobuf::Message for FieldChangeset { + fn is_initialized(&self) -> bool { + if let Some(FieldChangeset_oneof_one_of_type_options::type_options(ref v)) = self.one_of_type_options { + if !v.is_initialized() { + return false; + } + } + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_name = ::std::option::Option::Some(FieldChangeset_oneof_one_of_name::name(is.read_string()?)); + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_desc = ::std::option::Option::Some(FieldChangeset_oneof_one_of_desc::desc(is.read_string()?)); + }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_field_type = ::std::option::Option::Some(FieldChangeset_oneof_one_of_field_type::field_type(is.read_enum()?)); + }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_frozen = ::std::option::Option::Some(FieldChangeset_oneof_one_of_frozen::frozen(is.read_bool()?)); + }, + 6 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_visibility = ::std::option::Option::Some(FieldChangeset_oneof_one_of_visibility::visibility(is.read_bool()?)); + }, + 7 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_width = ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(is.read_int32()?)); + }, + 8 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(is.read_message()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.field_id); + } + if let ::std::option::Option::Some(ref v) = self.one_of_name { + match v { + &FieldChangeset_oneof_one_of_name::name(ref v) => { + my_size += ::protobuf::rt::string_size(2, &v); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_desc { + match v { + &FieldChangeset_oneof_one_of_desc::desc(ref v) => { + my_size += ::protobuf::rt::string_size(3, &v); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_field_type { + match v { + &FieldChangeset_oneof_one_of_field_type::field_type(v) => { + my_size += ::protobuf::rt::enum_size(4, v); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_frozen { + match v { + &FieldChangeset_oneof_one_of_frozen::frozen(v) => { + my_size += 2; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_visibility { + match v { + &FieldChangeset_oneof_one_of_visibility::visibility(v) => { + my_size += 2; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_width { + match v { + &FieldChangeset_oneof_one_of_width::width(v) => { + my_size += ::protobuf::rt::value_size(7, v, ::protobuf::wire_format::WireTypeVarint); + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_type_options { + match v { + &FieldChangeset_oneof_one_of_type_options::type_options(ref v) => { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.field_id.is_empty() { + os.write_string(1, &self.field_id)?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_name { + match v { + &FieldChangeset_oneof_one_of_name::name(ref v) => { + os.write_string(2, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_desc { + match v { + &FieldChangeset_oneof_one_of_desc::desc(ref v) => { + os.write_string(3, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_field_type { + match v { + &FieldChangeset_oneof_one_of_field_type::field_type(v) => { + os.write_enum(4, ::protobuf::ProtobufEnum::value(&v))?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_frozen { + match v { + &FieldChangeset_oneof_one_of_frozen::frozen(v) => { + os.write_bool(5, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_visibility { + match v { + &FieldChangeset_oneof_one_of_visibility::visibility(v) => { + os.write_bool(6, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_width { + match v { + &FieldChangeset_oneof_one_of_width::width(v) => { + os.write_int32(7, v)?; + }, + }; + } + if let ::std::option::Option::Some(ref v) = self.one_of_type_options { + match v { + &FieldChangeset_oneof_one_of_type_options::type_options(ref v) => { + os.write_tag(8, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> FieldChangeset { + FieldChangeset::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &FieldChangeset| { &m.field_id }, + |m: &mut FieldChangeset| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "name", + FieldChangeset::has_name, + FieldChangeset::get_name, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "desc", + FieldChangeset::has_desc, + FieldChangeset::get_desc, + )); + fields.push(::protobuf::reflect::accessor::make_singular_enum_accessor::<_, FieldType>( + "field_type", + FieldChangeset::has_field_type, + FieldChangeset::get_field_type, + )); + fields.push(::protobuf::reflect::accessor::make_singular_bool_accessor::<_>( + "frozen", + FieldChangeset::has_frozen, + FieldChangeset::get_frozen, + )); + fields.push(::protobuf::reflect::accessor::make_singular_bool_accessor::<_>( + "visibility", + FieldChangeset::has_visibility, + FieldChangeset::get_visibility, + )); + fields.push(::protobuf::reflect::accessor::make_singular_i32_accessor::<_>( + "width", + FieldChangeset::has_width, + FieldChangeset::get_width, + )); + fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, AnyData>( + "type_options", + FieldChangeset::has_type_options, + FieldChangeset::get_type_options, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "FieldChangeset", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static FieldChangeset { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(FieldChangeset::new) + } +} + +impl ::protobuf::Clear for FieldChangeset { + fn clear(&mut self) { + self.field_id.clear(); + self.one_of_name = ::std::option::Option::None; + self.one_of_desc = ::std::option::Option::None; + self.one_of_field_type = ::std::option::Option::None; + self.one_of_frozen = ::std::option::Option::None; + self.one_of_visibility = ::std::option::Option::None; + self.one_of_width = ::std::option::Option::None; + self.one_of_type_options = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for FieldChangeset { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for FieldChangeset { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct AnyData { // message fields @@ -2537,43 +3176,53 @@ impl ::protobuf::reflect::ProtobufValue for FieldType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\nmeta.proto\"c\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \n\nmeta.proto\"g\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ \x06gridId\x12\x1e\n\x06fields\x18\x02\x20\x03(\x0b2\x06.FieldR\x06field\ - s\x12\x1e\n\x06blocks\x18\x03\x20\x03(\x0b2\x06.BlockR\x06blocks\"\\\n\ - \x05Block\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12&\n\x0fstart_row_\ - index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\ - \x20\x01(\x05R\x08rowCount\"D\n\tBlockMeta\x12\x19\n\x08block_id\x18\x01\ - \x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.RowM\ - etaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ - \x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ + s\x12\"\n\x06blocks\x18\x03\x20\x03(\x0b2\n.GridBlockR\x06blocks\"`\n\tG\ + ridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12&\n\x0fstart_row_i\ + ndex\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\ + \x20\x01(\x05R\x08rowCount\"H\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\ + \x01\x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.\ + RowMetaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\t\ + R\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\ FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ idth\x18\x07\x20\x01(\x05R\x05width\x12+\n\x0ctype_options\x18\x08\x20\ \x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\rRepeatedField\x12\x1c\n\x05\ - items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"8\n\x07AnyData\x12\x17\ - \n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\ - \x20\x01(\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\ - \x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\ - \x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByFiel\ - dIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06he\ - ight\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\n\x12C\ - ellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\ - \x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\xa7\x02\ - \n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ - \x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\n\nvisib\ - ility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_field_id\ - \x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rcellByFiel\ - dId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\ - \x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\ - \x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"\x82\x01\n\ - \x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06row_\ - id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\t\ - R\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\x08.AnyDataR\x04dat\ - a\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06height*d\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\x08Checkbox\x10\x05b\x06proto3\ + items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"\x87\x03\n\x0eFieldChan\ + geset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04\ + name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\t\ + H\x01R\x04desc\x12+\n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeH\x02\ + R\tfieldType\x12\x18\n\x06frozen\x18\x05\x20\x01(\x08H\x03R\x06frozen\ + \x12\x20\n\nvisibility\x18\x06\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\ + \x05width\x18\x07\x20\x01(\x05H\x05R\x05width\x12-\n\x0ctype_options\x18\ + \x08\x20\x01(\x0b2\x08.AnyDataH\x06R\x0btypeOptionsB\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\x15\n\x13one_of_type\ + _options\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typ\ + eId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07Row\ + Meta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\ + \x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\ + \x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\ + \x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\ + \x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\ + \x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\ + \x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\ + \x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\ + \0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibili\ + ty\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.Ce\ + llByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\ + \x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\ + \x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one\ + _of_visibility\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ + \tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08\ + field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\ + \x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05\ + R\x06height*d\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\x08Checkbox\x10\x05b\x06prot\ + o3\ "; 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/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index dc00b1e72c..bba2c8c8dc 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -3,14 +3,14 @@ syntax = "proto3"; message GridMeta { string grid_id = 1; repeated Field fields = 2; - repeated Block blocks = 3; + repeated GridBlock blocks = 3; } -message Block { +message GridBlock { string id = 1; int32 start_row_index = 2; int32 row_count = 3; } -message BlockMeta { +message GridBlockMeta { string block_id = 1; repeated RowMeta rows = 2; } @@ -27,6 +27,16 @@ message Field { message RepeatedField { repeated Field items = 1; } +message FieldChangeset { + string field_id = 1; + oneof one_of_name { string name = 2; }; + oneof one_of_desc { string desc = 3; }; + oneof one_of_field_type { FieldType field_type = 4; }; + oneof one_of_frozen { bool frozen = 5; }; + oneof one_of_visibility { bool visibility = 6; }; + oneof one_of_width { int32 width = 7; }; + oneof one_of_type_options { AnyData type_options = 8; }; +} message AnyData { string type_id = 1; bytes value = 2; From df399d3f3535f8a211e2844c520b43d2726d953a Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 11 Mar 2022 22:07:01 +0800 Subject: [PATCH 12/28] feat: support option enum in pb --- .../flowy-grid-data-model/meta.pb.dart | 82 ++-- .../flowy-grid-data-model/meta.pbjson.dart | 20 +- frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- .../flowy-derive/src/proto_buf/deserialize.rs | 5 +- .../flowy-derive/src/proto_buf/serialize.rs | 6 + shared-lib/flowy-derive/src/proto_buf/util.rs | 8 +- .../src/protobuf/model/meta.rs | 400 +++++++++--------- .../src/protobuf/proto/meta.proto | 6 +- 8 files changed, 267 insertions(+), 264 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 3b5d6f5dad..344bef10da 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -353,47 +353,6 @@ class Field extends $pb.GeneratedMessage { AnyData ensureTypeOptions() => $_ensure(7); } -class RepeatedField extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedField', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Field.create) - ..hasRequiredFields = false - ; - - RepeatedField._() : super(); - factory RepeatedField({ - $core.Iterable? items, - }) { - final _result = create(); - if (items != null) { - _result.items.addAll(items); - } - return _result; - } - factory RepeatedField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RepeatedField.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RepeatedField clone() => RepeatedField()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RepeatedField copyWith(void Function(RepeatedField) updates) => super.copyWith((message) => updates(message as RepeatedField)) as RepeatedField; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RepeatedField create() => RepeatedField._(); - RepeatedField createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RepeatedField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RepeatedField? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get items => $_getList(0); -} - enum FieldChangeset_OneOfName { name, notSet @@ -632,6 +591,47 @@ class FieldChangeset extends $pb.GeneratedMessage { AnyData ensureTypeOptions() => $_ensure(7); } +class RepeatedField extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedField', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Field.create) + ..hasRequiredFields = false + ; + + RepeatedField._() : super(); + factory RepeatedField({ + $core.Iterable? items, + }) { + final _result = create(); + if (items != null) { + _result.items.addAll(items); + } + return _result; + } + factory RepeatedField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedField.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RepeatedField clone() => RepeatedField()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RepeatedField copyWith(void Function(RepeatedField) updates) => super.copyWith((message) => updates(message as RepeatedField)) as RepeatedField; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RepeatedField create() => RepeatedField._(); + RepeatedField createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RepeatedField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedField? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get items => $_getList(0); +} + class AnyData extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AnyData', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeId') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index c955a005fb..04e7384c15 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -75,16 +75,6 @@ const Field$json = const { /// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIrCgx0eXBlX29wdGlvbnMYCCABKAsyCC5BbnlEYXRhUgt0eXBlT3B0aW9ucw=='); -@$core.Deprecated('Use repeatedFieldDescriptor instead') -const RepeatedField$json = const { - '1': 'RepeatedField', - '2': const [ - const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Field', '10': 'items'}, - ], -}; - -/// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z'); @$core.Deprecated('Use fieldChangesetDescriptor instead') const FieldChangeset$json = const { '1': 'FieldChangeset', @@ -111,6 +101,16 @@ const FieldChangeset$json = const { /// Descriptor for `FieldChangeset`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldChangesetDescriptor = $convert.base64Decode('Cg5GaWVsZENoYW5nZXNldBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBIUCgRuYW1lGAIgASgJSABSBG5hbWUSFAoEZGVzYxgDIAEoCUgBUgRkZXNjEisKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVIAlIJZmllbGRUeXBlEhgKBmZyb3plbhgFIAEoCEgDUgZmcm96ZW4SIAoKdmlzaWJpbGl0eRgGIAEoCEgEUgp2aXNpYmlsaXR5EhYKBXdpZHRoGAcgASgFSAVSBXdpZHRoEi0KDHR5cGVfb3B0aW9ucxgIIAEoCzIILkFueURhdGFIBlILdHlwZU9wdGlvbnNCDQoLb25lX29mX25hbWVCDQoLb25lX29mX2Rlc2NCEwoRb25lX29mX2ZpZWxkX3R5cGVCDwoNb25lX29mX2Zyb3plbkITChFvbmVfb2ZfdmlzaWJpbGl0eUIOCgxvbmVfb2Zfd2lkdGhCFQoTb25lX29mX3R5cGVfb3B0aW9ucw=='); +@$core.Deprecated('Use repeatedFieldDescriptor instead') +const RepeatedField$json = const { + '1': 'RepeatedField', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Field', '10': 'items'}, + ], +}; + +/// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z'); @$core.Deprecated('Use anyDataDescriptor instead') const AnyData$json = const { '1': 'AnyData', diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 046fd85668..96755db623 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [lib] name = "dart_ffi" # this value will change depending on the target os -# default cdylib -crate-type = ["cdylib"] +# default staticlib +crate-type = ["staticlib"] [dependencies] diff --git a/shared-lib/flowy-derive/src/proto_buf/deserialize.rs b/shared-lib/flowy-derive/src/proto_buf/deserialize.rs index a971279b21..e09f7ea847 100644 --- a/shared-lib/flowy-derive/src/proto_buf/deserialize.rs +++ b/shared-lib/flowy-derive/src/proto_buf/deserialize.rs @@ -55,14 +55,11 @@ fn token_stream_for_one_of(ctxt: &Ctxt, field: &ASTField) -> Option } }?; let bracketed_ty_info = ty_info.bracket_ty_info.as_ref().as_ref(); - let has_func = format_ident!("has_{}", ident.to_string()); - // eprintln!("😁{:#?}", ty_info.primitive_ty); - // eprintln!("{:#?}", ty_info.bracket_ty_info); match ident_category(bracketed_ty_info.unwrap().ident) { TypeCategory::Enum => { let get_func = format_ident!("get_{}", ident.to_string()); - let ty = ty_info.ty; + let ty = bracketed_ty_info.unwrap().ty; Some(quote! { if pb.#has_func() { let enum_de_from_pb = #ty::try_from(&pb.#get_func()).unwrap(); diff --git a/shared-lib/flowy-derive/src/proto_buf/serialize.rs b/shared-lib/flowy-derive/src/proto_buf/serialize.rs index eff797a310..324c26651b 100644 --- a/shared-lib/flowy-derive/src/proto_buf/serialize.rs +++ b/shared-lib/flowy-derive/src/proto_buf/serialize.rs @@ -71,6 +71,12 @@ fn token_stream_for_one_of(ctxt: &Ctxt, field: &ASTField) -> Option None => {} } }), + TypeCategory::Enum => Some(quote! { + match self.#member { + Some(s) => { pb.#set_func(s.try_into().unwrap()) } + None => {} + } + }), _ => Some(quote! { match self.#member { Some(ref s) => { pb.#set_func(s.clone()) } diff --git a/shared-lib/flowy-derive/src/proto_buf/util.rs b/shared-lib/flowy-derive/src/proto_buf/util.rs index 49a5ee1605..ef9391fa0d 100644 --- a/shared-lib/flowy-derive/src/proto_buf/util.rs +++ b/shared-lib/flowy-derive/src/proto_buf/util.rs @@ -74,14 +74,14 @@ pub fn category_from_str(type_str: String) -> TypeCategory { } } - if let Some(protobuf) = CACHE_INFO.get(&TypeCategory::Protobuf) { - if protobuf.contains(&type_str) { + if let Some(protobuf_tys) = CACHE_INFO.get(&TypeCategory::Protobuf) { + if protobuf_tys.contains(&type_str) { return TypeCategory::Protobuf; } } - if let Some(protobuf) = CACHE_INFO.get(&TypeCategory::Enum) { - if protobuf.contains(&type_str) { + if let Some(enum_tys) = CACHE_INFO.get(&TypeCategory::Enum) { + if enum_tys.contains(&type_str) { return TypeCategory::Enum; } } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index 4ef31470a8..4cb13bf25e 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -1153,172 +1153,6 @@ impl ::protobuf::reflect::ProtobufValue for Field { } } -#[derive(PartialEq,Clone,Default)] -pub struct RepeatedField { - // message fields - pub items: ::protobuf::RepeatedField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RepeatedField { - fn default() -> &'a RepeatedField { - ::default_instance() - } -} - -impl RepeatedField { - pub fn new() -> RepeatedField { - ::std::default::Default::default() - } - - // repeated .Field items = 1; - - - pub fn get_items(&self) -> &[Field] { - &self.items - } - pub fn clear_items(&mut self) { - self.items.clear(); - } - - // Param is passed by value, moved - pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { - self.items = v; - } - - // Mutable pointer to the field. - pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.items - } - - // Take field - pub fn take_items(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for RepeatedField { - fn is_initialized(&self) -> bool { - for v in &self.items { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.items { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.items { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RepeatedField { - RepeatedField::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "items", - |m: &RepeatedField| { &m.items }, - |m: &mut RepeatedField| { &mut m.items }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RepeatedField", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RepeatedField { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RepeatedField::new) - } -} - -impl ::protobuf::Clear for RepeatedField { - fn clear(&mut self) { - self.items.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RepeatedField { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RepeatedField { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct FieldChangeset { // message fields @@ -1958,6 +1792,172 @@ impl ::protobuf::reflect::ProtobufValue for FieldChangeset { } } +#[derive(PartialEq,Clone,Default)] +pub struct RepeatedField { + // message fields + pub items: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RepeatedField { + fn default() -> &'a RepeatedField { + ::default_instance() + } +} + +impl RepeatedField { + pub fn new() -> RepeatedField { + ::std::default::Default::default() + } + + // repeated .Field items = 1; + + + pub fn get_items(&self) -> &[Field] { + &self.items + } + pub fn clear_items(&mut self) { + self.items.clear(); + } + + // Param is passed by value, moved + pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { + self.items = v; + } + + // Mutable pointer to the field. + pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.items + } + + // Take field + pub fn take_items(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for RepeatedField { + fn is_initialized(&self) -> bool { + for v in &self.items { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.items { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.items { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RepeatedField { + RepeatedField::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "items", + |m: &RepeatedField| { &m.items }, + |m: &mut RepeatedField| { &mut m.items }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedField", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RepeatedField { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedField::new) + } +} + +impl ::protobuf::Clear for RepeatedField { + fn clear(&mut self) { + self.items.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RepeatedField { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RepeatedField { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct AnyData { // message fields @@ -3189,40 +3189,40 @@ static file_descriptor_proto_data: &'static [u8] = b"\ FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ idth\x18\x07\x20\x01(\x05R\x05width\x12+\n\x0ctype_options\x18\x08\x20\ - \x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\rRepeatedField\x12\x1c\n\x05\ - items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"\x87\x03\n\x0eFieldChan\ - geset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04\ - name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\t\ - H\x01R\x04desc\x12+\n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeH\x02\ - R\tfieldType\x12\x18\n\x06frozen\x18\x05\x20\x01(\x08H\x03R\x06frozen\ - \x12\x20\n\nvisibility\x18\x06\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\ - \x05width\x18\x07\x20\x01(\x05H\x05R\x05width\x12-\n\x0ctype_options\x18\ - \x08\x20\x01(\x0b2\x08.AnyDataH\x06R\x0btypeOptionsB\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\x15\n\x13one_of_type\ - _options\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typ\ - eId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07Row\ - Meta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\ - \x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\ - \x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\ - \x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\ - \x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\ - \x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\ - \x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\ - \x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\ - \0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibili\ - ty\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.Ce\ - llByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\ - \x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\ - \x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one\ - _of_visibility\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ - \tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08\ - field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\ - \x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05\ - R\x06height*d\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\x08Checkbox\x10\x05b\x06prot\ - o3\ + \x01(\x0b2\x08.AnyDataR\x0btypeOptions\"\x87\x03\n\x0eFieldChangeset\x12\ + \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04name\x18\ + \x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\ + \x04desc\x12+\n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeH\x02R\tfie\ + ldType\x12\x18\n\x06frozen\x18\x05\x20\x01(\x08H\x03R\x06frozen\x12\x20\ + \n\nvisibility\x18\x06\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\ + \x18\x07\x20\x01(\x05H\x05R\x05width\x12-\n\x0ctype_options\x18\x08\x20\ + \x01(\x0b2\x08.AnyDataH\x06R\x0btypeOptionsB\r\n\x0bone_of_nameB\r\n\x0b\ + one_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11\ + one_of_visibilityB\x0e\n\x0cone_of_widthB\x15\n\x13one_of_type_options\"\ + -\n\rRepeatedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\ + \x05items\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06ty\ + peId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07Ro\ + wMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\ + \x18\x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\ + \x03(\x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06h\ + eight\x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\ + \x01(\x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\ + \x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellM\ + etaR\x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row\ + _id\x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\ + \x05H\0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvis\ + ibility\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChanges\ + et.CellByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\ + \x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\ + \x01(\x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\ + \x11one_of_visibility\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\ + \x20\x01(\tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\ + \x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\ + \x04\x20\x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\ + \x01(\x05R\x06height*d\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\ + \x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index bba2c8c8dc..43c7e67d76 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -24,9 +24,6 @@ message Field { int32 width = 7; AnyData type_options = 8; } -message RepeatedField { - repeated Field items = 1; -} message FieldChangeset { string field_id = 1; oneof one_of_name { string name = 2; }; @@ -37,6 +34,9 @@ message FieldChangeset { oneof one_of_width { int32 width = 7; }; oneof one_of_type_options { AnyData type_options = 8; }; } +message RepeatedField { + repeated Field items = 1; +} message AnyData { string type_id = 1; bytes value = 2; From 6579940dc8f3d9f385baf51c471a56672ca1a5e1 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 12 Mar 2022 09:30:13 +0800 Subject: [PATCH 13/28] chore: create default grid --- .../flowy-folder-data-model/view.pb.dart | 6 +- .../flowy-folder-data-model/view.pbenum.dart | 4 +- .../flowy-folder-data-model/view.pbjson.dart | 4 +- frontend/rust-lib/flowy-block/src/editor.rs | 7 +- frontend/rust-lib/flowy-block/src/queue.rs | 1 - .../tests/document/document_test.rs | 2 +- .../flowy-block/tests/document/edit_script.rs | 2 +- frontend/rust-lib/flowy-folder/src/manager.rs | 10 +- .../src/services/folder_editor.rs | 10 +- .../src/services/persistence/migration.rs | 2 +- .../persistence/version_1/view_sql.rs | 4 +- .../src/services/view/controller.rs | 26 ++-- .../tests/workspace/folder_test.rs | 13 +- .../flowy-folder/tests/workspace/helper.rs | 3 +- .../flowy-folder/tests/workspace/script.rs | 23 ++-- .../rust-lib/flowy-grid/src/event_handler.rs | 4 +- frontend/rust-lib/flowy-grid/src/manager.rs | 32 ++++- .../flowy-grid/src/services/grid_builder.rs | 77 ------------ .../flowy-grid/src/services/grid_editor.rs | 68 ++++++----- .../src/services/grid_meta_editor.rs | 34 +++--- .../rust-lib/flowy-grid/src/services/mod.rs | 1 - .../rust-lib/flowy-grid/tests/grid_test.rs | 0 .../flowy-net/src/local_server/persistence.rs | 25 ++-- .../flowy-net/src/local_server/server.rs | 4 +- .../flowy-sdk/src/deps_resolve/folder_deps.rs | 52 ++++++-- .../src/cache/disk/grid_meta_rev_impl.rs | 4 +- .../src/cache/disk/grid_rev_impl.rs | 4 +- .../rust-lib/flowy-sync/src/cache/disk/mod.rs | 2 - .../src/cache/disk/text_rev_impl.rs | 4 +- .../rust-lib/flowy-sync/src/rev_manager.rs | 1 - frontend/rust-lib/flowy-test/src/helper.rs | 2 +- .../src/client_grid/block_pad.rs | 37 ++++-- .../src/client_grid/grid_builder.rs | 114 ++++++++++++++++++ .../src/client_grid/grid_pad.rs | 21 ++-- .../src/client_grid/mod.rs | 2 + .../src/server_document/document_manager.rs | 31 ++--- .../src/entities/view.rs | 8 +- .../src/protobuf/model/view.rs | 36 +++--- .../src/protobuf/proto/view.proto | 2 +- .../src/user_default.rs | 2 +- .../src/entities/meta.rs | 17 ++- .../flowy-grid-data-model/tests/serde_test.rs | 4 +- 42 files changed, 412 insertions(+), 293 deletions(-) delete mode 100644 frontend/rust-lib/flowy-grid/src/services/grid_builder.rs create mode 100644 frontend/rust-lib/flowy-grid/tests/grid_test.rs create mode 100644 shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart index bc0b49b833..b79716fd25 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart @@ -20,7 +20,7 @@ class View extends $pb.GeneratedMessage { ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'belongToId') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') - ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.Block, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) + ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) ..aInt64(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'version') ..aOM(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'belongings', subBuilder: RepeatedView.create) ..aInt64(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'modifiedTime') @@ -274,7 +274,7 @@ class CreateViewPayload extends $pb.GeneratedMessage { ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') - ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.Block, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) + ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData') ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) ..hasRequiredFields = false @@ -408,7 +408,7 @@ class CreateViewParams extends $pb.GeneratedMessage { ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') - ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.Block, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) + ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData') ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewId') ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbenum.dart index f644361742..aa7b0105b1 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbenum.dart @@ -10,11 +10,11 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; class ViewDataType extends $pb.ProtobufEnum { - static const ViewDataType Block = ViewDataType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Block'); + static const ViewDataType TextBlock = ViewDataType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TextBlock'); static const ViewDataType Grid = ViewDataType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Grid'); static const $core.List values = [ - Block, + TextBlock, Grid, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart index 87ebb89969..adb1721475 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart @@ -12,13 +12,13 @@ import 'dart:typed_data' as $typed_data; const ViewDataType$json = const { '1': 'ViewDataType', '2': const [ - const {'1': 'Block', '2': 0}, + const {'1': 'TextBlock', '2': 0}, const {'1': 'Grid', '2': 1}, ], }; /// Descriptor for `ViewDataType`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List viewDataTypeDescriptor = $convert.base64Decode('CgxWaWV3RGF0YVR5cGUSCQoFQmxvY2sQABIICgRHcmlkEAE='); +final $typed_data.Uint8List viewDataTypeDescriptor = $convert.base64Decode('CgxWaWV3RGF0YVR5cGUSDQoJVGV4dEJsb2NrEAASCAoER3JpZBAB'); @$core.Deprecated('Use viewDescriptor instead') const View$json = const { '1': 'View', diff --git a/frontend/rust-lib/flowy-block/src/editor.rs b/frontend/rust-lib/flowy-block/src/editor.rs index fa3c1c757c..b5e9e81810 100644 --- a/frontend/rust-lib/flowy-block/src/editor.rs +++ b/frontend/rust-lib/flowy-block/src/editor.rs @@ -1,4 +1,3 @@ -use crate::queue::TextBlockRevisionCompactor; use crate::web_socket::{make_block_ws_manager, EditorCommandSender}; use crate::{ errors::FlowyError, @@ -40,7 +39,7 @@ impl ClientTextBlockEditor { rev_web_socket: Arc, cloud_service: Arc, ) -> FlowyResult> { - let document_info = rev_manager.load::(cloud_service).await?; + let document_info = rev_manager.load::(cloud_service).await?; let delta = document_info.delta()?; let rev_manager = Arc::new(rev_manager); let doc_id = doc_id.to_string(); @@ -213,8 +212,8 @@ impl ClientTextBlockEditor { } } -struct BlockInfoBuilder(); -impl RevisionObjectBuilder for BlockInfoBuilder { +struct TextBlockInfoBuilder(); +impl RevisionObjectBuilder for TextBlockInfoBuilder { type Output = TextBlockInfo; fn build_object(object_id: &str, revisions: Vec) -> FlowyResult { diff --git a/frontend/rust-lib/flowy-block/src/queue.rs b/frontend/rust-lib/flowy-block/src/queue.rs index c7683e9f0f..087ed9d189 100644 --- a/frontend/rust-lib/flowy-block/src/queue.rs +++ b/frontend/rust-lib/flowy-block/src/queue.rs @@ -11,7 +11,6 @@ use flowy_collaboration::{ use flowy_error::{FlowyError, FlowyResult}; use flowy_sync::{DeltaMD5, RevisionCompactor, RevisionManager, RichTextTransformDeltas, TransformDeltas}; use futures::stream::StreamExt; -use lib_ot::core::{Attributes, Delta}; use lib_ot::{ core::{Interval, OperationTransformable}, rich_text::{RichTextAttribute, RichTextAttributes, RichTextDelta}, diff --git a/frontend/rust-lib/flowy-block/tests/document/document_test.rs b/frontend/rust-lib/flowy-block/tests/document/document_test.rs index 86fd1d4a2e..df2282d01f 100644 --- a/frontend/rust-lib/flowy-block/tests/document/document_test.rs +++ b/frontend/rust-lib/flowy-block/tests/document/document_test.rs @@ -1,5 +1,5 @@ use crate::document::edit_script::{EditorScript::*, *}; -use flowy_collaboration::entities::revision::RevisionState; +use flowy_sync::disk::RevisionState; use lib_ot::core::{count_utf16_code_units, Interval}; #[tokio::test] diff --git a/frontend/rust-lib/flowy-block/tests/document/edit_script.rs b/frontend/rust-lib/flowy-block/tests/document/edit_script.rs index a06eb24a44..c30ccd8d46 100644 --- a/frontend/rust-lib/flowy-block/tests/document/edit_script.rs +++ b/frontend/rust-lib/flowy-block/tests/document/edit_script.rs @@ -1,6 +1,6 @@ use flowy_block::editor::ClientTextBlockEditor; use flowy_block::DOCUMENT_SYNC_INTERVAL_IN_MILLIS; -use flowy_collaboration::entities::revision::RevisionState; +use flowy_sync::disk::RevisionState; use flowy_test::{helper::ViewTest, FlowySDKTest}; use lib_ot::{core::Interval, rich_text::RichTextDelta}; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 3ccb00466e..ffa6fc26cb 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -12,7 +12,7 @@ use bytes::Bytes; use chrono::Utc; use flowy_collaboration::client_document::default::{initial_quill_delta_string, initial_read_me}; -use flowy_collaboration::entities::revision::RepeatedRevision; + use flowy_collaboration::{client_folder::FolderPad, entities::ws_data::ServerRevisionWSData}; use flowy_error::FlowyError; use flowy_folder_data_model::entities::view::ViewDataType; @@ -164,7 +164,7 @@ impl FolderManager { let _ = self.persistence.initialize(user_id, &folder_id).await?; let pool = self.persistence.db_pool()?; - let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(&user_id, pool)); + let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(user_id, pool)); 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); @@ -214,7 +214,7 @@ impl DefaultFolderBuilder { }; let _ = view_controller.set_latest_view(&view.id); let _ = view_controller - .create_view(&view.id, ViewDataType::Block, Bytes::from(view_data)) + .create_view(&view.id, ViewDataType::TextBlock, Bytes::from(view_data)) .await?; } } @@ -239,7 +239,7 @@ impl FolderManager { pub trait ViewDataProcessor { fn initialize(&self) -> FutureResult<(), FlowyError>; - fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FutureResult<(), FlowyError>; + fn create_container(&self, user_id: &str, view_id: &str, delta_data: Bytes) -> FutureResult<(), FlowyError>; fn delete_container(&self, view_id: &str) -> FutureResult<(), FlowyError>; @@ -247,7 +247,7 @@ pub trait ViewDataProcessor { fn delta_str(&self, view_id: &str) -> FutureResult; - fn default_view_data(&self, view_id: &str) -> String; + fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult; fn data_type(&self) -> ViewDataType; } 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 203c7c4cec..0a5dd7f794 100644 --- a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs +++ b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs @@ -8,14 +8,14 @@ use crate::manager::FolderId; use bytes::Bytes; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; -use flowy_sync::disk::RevisionDiskCache; + use flowy_sync::{ - RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, - RevisionWebSocket, RevisionWebSocketManager, + RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionWebSocket, + RevisionWebSocketManager, }; use lib_infra::future::FutureResult; -use lib_ot::core::{Delta, PlainTextAttributes}; -use lib_sqlite::ConnectionPool; +use lib_ot::core::PlainTextAttributes; + use parking_lot::RwLock; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs index 20e6d71c66..c08a4c226e 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs @@ -88,7 +88,7 @@ impl FolderMigration { return Ok(None); } let pool = self.database.db_pool()?; - let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(&user_id, pool)); + let disk_cache = Arc::new(SQLiteTextBlockRevisionPersistence::new(user_id, pool)); let rev_persistence = Arc::new(RevisionPersistence::new(user_id, folder_id.as_ref(), disk_cache)); let (revisions, _) = RevisionLoader { object_id: folder_id.as_ref().to_owned(), diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs index c854021b80..a41f3c49c2 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs @@ -84,7 +84,7 @@ pub(crate) struct ViewTable { impl ViewTable { pub fn new(view: View) -> Self { let data_type = match view.data_type { - ViewDataType::Block => SqlViewDataType::Block, + ViewDataType::TextBlock => SqlViewDataType::Block, ViewDataType::Grid => SqlViewDataType::Grid, }; @@ -106,7 +106,7 @@ impl ViewTable { impl std::convert::From for View { fn from(table: ViewTable) -> Self { let data_type = match table.view_type { - SqlViewDataType::Block => ViewDataType::Block, + SqlViewDataType::Block => ViewDataType::TextBlock, SqlViewDataType::Grid => ViewDataType::Grid, }; 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 4722aaad5d..79ce91e3bb 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -13,10 +13,7 @@ use crate::{ }, }; use bytes::Bytes; -use flowy_collaboration::entities::{ - revision::{RepeatedRevision, Revision}, - text_block_info::TextBlockId, -}; +use flowy_collaboration::entities::text_block_info::TextBlockId; use flowy_database::kv::KV; use flowy_folder_data_model::entities::view::ViewDataType; use futures::{FutureExt, StreamExt}; @@ -58,18 +55,18 @@ impl ViewController { #[tracing::instrument(level = "trace", skip(self, params), fields(name = %params.name), err)] pub(crate) async fn create_view_from_params(&self, mut params: CreateViewParams) -> Result { let processor = self.get_data_processor(¶ms.data_type)?; - let content = if params.data.is_empty() { - let default_view_data = processor.default_view_data(¶ms.view_id); - params.data = default_view_data.clone(); - default_view_data + + if params.data.is_empty() { + let user_id = self.user.user_id()?; + let view_data = processor.create_default_view(&user_id, ¶ms.view_id).await?; + params.data = view_data; } else { - params.data.clone() + let delta_data = Bytes::from(params.data.clone()); + let _ = self + .create_view(¶ms.view_id, params.data_type.clone(), delta_data) + .await?; }; - let delta_data = Bytes::from(content); - let _ = self - .create_view(¶ms.view_id, params.data_type.clone(), delta_data) - .await?; let view = self.create_view_on_server(params).await?; let _ = self.create_view_on_local(view.clone()).await?; Ok(view) @@ -86,9 +83,8 @@ impl ViewController { return Err(FlowyError::internal().context("The content of the view should not be empty")); } let user_id = self.user.user_id()?; - let repeated_revision: RepeatedRevision = Revision::initial_revision(&user_id, view_id, delta_data).into(); let processor = self.get_data_processor(&data_type)?; - let _ = processor.create_container(view_id, repeated_revision).await?; + let _ = processor.create_container(&user_id, view_id, delta_data).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs b/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs index 18a11d9a0b..7dd5b66e2f 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs @@ -1,6 +1,7 @@ use crate::script::{invalid_workspace_name_test_case, FolderScript::*, FolderTest}; -use flowy_collaboration::{client_document::default::initial_quill_delta_string, entities::revision::RevisionState}; + use flowy_folder::entities::workspace::CreateWorkspacePayload; +use flowy_sync::disk::RevisionState; use flowy_test::{event_builder::*, FlowySDKTest}; #[tokio::test] @@ -168,16 +169,6 @@ async fn view_update() { assert_eq!(test.view.name, new_name); } -#[tokio::test] -async fn open_document_view() { - let mut test = FolderTest::new().await; - assert_eq!(test.document_info, None); - - test.run_scripts(vec![OpenDocument]).await; - let document_info = test.document_info.unwrap(); - assert_eq!(document_info.text, initial_quill_delta_string()); -} - #[tokio::test] #[should_panic] async fn view_delete() { diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs b/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs index 393c0f5699..93e2ff2b7f 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs @@ -161,7 +161,8 @@ pub async fn delete_view(sdk: &FlowySDKTest, view_ids: Vec) { .await; } -pub async fn open_document(sdk: &FlowySDKTest, view_id: &str) -> TextBlockInfo { +#[allow(dead_code)] +pub async fn set_latest_view(sdk: &FlowySDKTest, view_id: &str) -> TextBlockInfo { let view_id: ViewId = view_id.into(); FolderEventBuilder::new(sdk.clone()) .event(SetLatestView) diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index e4298b54e7..7674ca0a54 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 crate::helper::*; -use flowy_collaboration::entities::{revision::RevisionState, text_block_info::TextBlockInfo}; + use flowy_folder::{errors::ErrorCode, services::folder_editor::ClientFolderEditor}; use flowy_folder_data_model::entities::{ app::{App, RepeatedApp}, @@ -7,6 +7,7 @@ use flowy_folder_data_model::entities::{ view::{RepeatedView, View, ViewDataType}, workspace::Workspace, }; +use flowy_sync::disk::RevisionState; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::FlowySDKTest; use std::{sync::Arc, time::Duration}; @@ -42,9 +43,6 @@ pub enum FolderScript { ReadTrash, DeleteAllTrash, - // Document - OpenDocument, - // Sync AssertCurrentRevId(i64), AssertNextSyncRevId(Option), @@ -58,7 +56,6 @@ pub struct FolderTest { pub app: App, pub view: View, pub trash: Vec, - pub document_info: Option, // pub folder_editor: } @@ -68,7 +65,14 @@ impl FolderTest { let _ = sdk.init_user().await; let mut workspace = create_workspace(&sdk, "FolderWorkspace", "Folder test workspace").await; let mut app = create_app(&sdk, &workspace.id, "Folder App", "Folder test app").await; - let view = create_view(&sdk, &app.id, "Folder View", "Folder test view", ViewDataType::Block).await; + let view = create_view( + &sdk, + &app.id, + "Folder View", + "Folder test view", + ViewDataType::TextBlock, + ) + .await; app.belongings = RepeatedView { items: vec![view.clone()], }; @@ -83,7 +87,6 @@ impl FolderTest { app, view, trash: vec![], - document_info: None, } } @@ -146,7 +149,7 @@ impl FolderTest { } FolderScript::CreateView { name, desc } => { - let view = create_view(sdk, &self.app.id, &name, &desc, ViewDataType::Block).await; + let view = create_view(sdk, &self.app.id, &name, &desc, ViewDataType::TextBlock).await; self.view = view; } FolderScript::AssertView(view) => { @@ -179,10 +182,6 @@ impl FolderTest { delete_all_trash(sdk).await; self.trash = vec![]; } - FolderScript::OpenDocument => { - let document_info = open_document(sdk, &self.view.id).await; - self.document_info = Some(document_info); - } FolderScript::AssertRevisionState { rev_id, state } => { let record = cache.get(rev_id).await.unwrap(); assert_eq!(record.state, state); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 8c91bf1341..b621d30a69 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -46,7 +46,7 @@ pub(crate) async fn create_row_handler( ) -> Result<(), FlowyError> { let id: GridId = data.into_inner(); let editor = manager.get_grid_editor(id.as_ref())?; - let _ = editor.create_empty_row().await?; + let _ = editor.create_row().await?; Ok(()) } @@ -55,7 +55,7 @@ pub(crate) async fn update_cell_handler( data: Data, manager: AppData>, ) -> Result<(), FlowyError> { - let cell: Cell = data.into_inner(); + let _cell: Cell = data.into_inner(); // let editor = manager.get_grid_editor(id.as_ref())?; // let _ = editor.create_empty_row().await?; Ok(()) diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 6c5aa8236a..05e61b26ce 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -1,13 +1,10 @@ use crate::services::grid_editor::ClientGridEditor; -use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; +use crate::services::kv_persistence::GridKVPersistence; use dashmap::DashMap; - use flowy_collaboration::entities::revision::RepeatedRevision; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{Field, RowMeta}; +use flowy_sync::disk::{SQLiteGridBlockMetaRevisionPersistence, SQLiteGridRevisionPersistence}; use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; - -use flowy_sync::disk::SQLiteGridRevisionPersistence; use lib_sqlite::ConnectionPool; use parking_lot::RwLock; use std::sync::Arc; @@ -47,6 +44,19 @@ impl GridManager { Ok(()) } + #[tracing::instrument(level = "debug", skip_all, err)] + pub async fn create_grid_block_meta>( + &self, + block_id: T, + revisions: RepeatedRevision, + ) -> FlowyResult<()> { + let block_id = block_id.as_ref(); + let db_pool = self.grid_user.db_pool()?; + let rev_manager = self.make_grid_block_meta_rev_manager(block_id, db_pool)?; + let _ = rev_manager.reset_object(revisions).await?; + Ok(()) + } + #[tracing::instrument(level = "debug", skip_all, fields(grid_id), err)] pub async fn open_grid>(&self, grid_id: T) -> FlowyResult> { let grid_id = grid_id.as_ref(); @@ -112,6 +122,18 @@ impl GridManager { Ok(rev_manager) } + fn make_grid_block_meta_rev_manager( + &self, + block_d: &str, + pool: Arc, + ) -> FlowyResult { + let user_id = self.grid_user.user_id()?; + let disk_cache = Arc::new(SQLiteGridBlockMetaRevisionPersistence::new(&user_id, pool)); + let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, block_d, disk_cache)); + let rev_manager = RevisionManager::new(&user_id, block_d, rev_persistence); + Ok(rev_manager) + } + fn get_kv_persistence(&self) -> FlowyResult> { let read_guard = self.kv_persistence.read(); if read_guard.is_some() { diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs deleted file mode 100644 index e74ad692d3..0000000000 --- a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs +++ /dev/null @@ -1,77 +0,0 @@ -use crate::manager::GridManager; -use flowy_collaboration::client_grid::make_grid_delta; -use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{CellMeta, Field, FieldType, Grid, GridMeta, RowMeta, RowOrder}; -use lib_infra::uuid; -use std::sync::Arc; - -pub struct GridBuilder { - grid_manager: Arc, - grid_id: String, - fields: Vec, - rows: Vec, -} - -impl GridBuilder { - pub fn new(grid_id: &str, grid_manager: Arc) -> Self { - Self { - grid_manager, - grid_id: grid_id.to_owned(), - fields: vec![], - rows: vec![], - } - } - - pub fn add_field(mut self, name: &str, desc: &str, field_type: FieldType) -> Self { - let field = Field::new(&uuid(), name, desc, field_type); - self.fields.push(field); - self - } - - pub fn add_empty_row(mut self) -> Self { - let row = RowMeta::new(&uuid(), &self.grid_id, vec![]); - self.rows.push(row); - self - } - - pub fn add_row(mut self, cells: Vec) -> Self { - let row = RowMeta::new(&uuid(), &self.grid_id, cells); - self.rows.push(row); - self - } - - pub fn build(self) -> FlowyResult { - let grid_meta = GridMeta { - grid_id: self.grid_id, - fields: self.fields, - blocks: vec![], - }; - - // let _ = check_rows(&self.fields, &self.rows)?; - let delta = make_grid_delta(&grid_meta); - Ok(delta.to_delta_str()) - } -} - -#[allow(dead_code)] -fn check_rows(fields: &[Field], rows: &[RowMeta]) -> FlowyResult<()> { - let field_ids = fields.iter().map(|field| &field.id).collect::>(); - for row in rows { - let cell_field_ids = row.cell_by_field_id.keys().into_iter().collect::>(); - if cell_field_ids != field_ids { - let msg = format!("{:?} contains invalid cells", row); - return Err(FlowyError::internal().context(msg)); - } - } - Ok(()) -} - -pub fn make_default_grid(grid_id: &str, grid_manager: Arc) -> String { - GridBuilder::new(grid_id, grid_manager) - .add_field("Name", "", FieldType::RichText) - .add_field("Tags", "", FieldType::SingleSelect) - .add_empty_row() - .add_empty_row() - .build() - .unwrap() -} 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 4fb93c16b2..f9cf627d83 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,6 +1,5 @@ use crate::manager::GridUser; use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; -use crate::services::stringify::stringify_deserialize; use crate::services::grid_meta_editor::ClientGridBlockMetaEditor; use bytes::Bytes; @@ -10,14 +9,14 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Cell, CellMeta, Field, Grid, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, RowMeta, + Field, Grid, GridBlock, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, +}; +use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; +use flowy_sync::{ + RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, }; -use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; -use lib_infra::uuid; -use lib_ot::core::{Delta, PlainTextAttributes}; -use rayon::iter::{IntoParallelIterator, ParallelIterator}; -use std::collections::HashMap; +use lib_ot::core::PlainTextAttributes; use std::sync::Arc; use tokio::sync::RwLock; @@ -40,10 +39,11 @@ impl ClientGridEditor { let token = user.token()?; let cloud = Arc::new(GridRevisionCloudService { token }); let grid_pad = rev_manager.load::(cloud).await?; - let rev_manager = Arc::new(rev_manager); let grid_meta_pad = Arc::new(RwLock::new(grid_pad)); - let block_meta_manager = Arc::new(GridBlockMetaEditorManager::new()); + + let block_meta_manager = + Arc::new(GridBlockMetaEditorManager::new(&user, grid_meta_pad.read().await.get_blocks()).await?); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), @@ -65,25 +65,15 @@ impl ClientGridEditor { Ok(()) } - pub async fn create_empty_row(&self) -> FlowyResult<()> { - // let _ = self.modify(|grid| { - // - // - // grid.blocks - // - // }).await?; + pub async fn create_row(&self) -> FlowyResult<()> { todo!() } - async fn create_row(&self, row: RowMeta) -> FlowyResult<()> { + pub async fn get_rows(&self, _row_orders: RepeatedRowOrder) -> FlowyResult { todo!() } - pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult { - todo!() - } - - pub async fn delete_rows(&self, ids: Vec) -> FlowyResult<()> { + pub async fn delete_rows(&self, _ids: Vec) -> FlowyResult<()> { todo!() } @@ -188,13 +178,17 @@ struct GridBlockMetaEditorManager { } impl GridBlockMetaEditorManager { - fn new() -> Self { - Self { - editor_map: DashMap::new(), - } + async fn new(user: &Arc, blocks: Vec) -> FlowyResult { + let editor_map = make_block_meta_editor_map(user, blocks).await?; + let manager = Self { editor_map }; + Ok(manager) } - pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult { + async fn get_editor(&self, _block_id: &str) -> Arc { + todo!() + } + + pub async fn get_rows(&self, _row_orders: RepeatedRowOrder) -> FlowyResult { // let ids = row_orders // .items // .into_iter() @@ -245,3 +239,23 @@ impl GridBlockMetaEditorManager { todo!() } } + +async fn make_block_meta_editor_map( + user: &Arc, + blocks: Vec, +) -> FlowyResult>> { + let token = user.token()?; + let user_id = user.user_id()?; + let pool = user.db_pool()?; + + let editor_map = DashMap::new(); + for block in blocks { + let disk_cache = Arc::new(SQLiteGridBlockMetaRevisionPersistence::new(&user_id, pool.clone())); + let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, &block.id, disk_cache)); + let rev_manager = RevisionManager::new(&user_id, &block.id, rev_persistence); + let editor = ClientGridBlockMetaEditor::new(&user_id, &token, &block.id, rev_manager).await?; + editor_map.insert(block.id, Arc::new(editor)); + } + + Ok(editor_map) +} diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs index 3e3e5e82d3..6704d6a718 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs @@ -3,17 +3,16 @@ use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::RowMeta; +use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset}; use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; -use lib_infra::uuid; use lib_ot::core::PlainTextAttributes; use std::sync::Arc; use tokio::sync::RwLock; pub struct ClientGridBlockMetaEditor { user_id: String, - block_id: String, + pub block_id: String, meta_pad: Arc>, rev_manager: Arc, } @@ -22,7 +21,7 @@ impl ClientGridBlockMetaEditor { pub async fn new( user_id: &str, token: &str, - block_id: String, + block_id: &str, mut rev_manager: RevisionManager, ) -> FlowyResult { let cloud = Arc::new(GridBlockMetaRevisionCloudService { @@ -32,6 +31,7 @@ impl ClientGridBlockMetaEditor { let meta_pad = Arc::new(RwLock::new(block_meta_pad)); let rev_manager = Arc::new(rev_manager); let user_id = user_id.to_owned(); + let block_id = block_id.to_owned(); Ok(Self { user_id, block_id, @@ -40,25 +40,27 @@ impl ClientGridBlockMetaEditor { }) } - pub async fn create_empty_row(&self) -> FlowyResult<()> { - let row = RowMeta::new(&uuid(), &self.block_id, vec![]); - self.create_row(row).await?; - Ok(()) - } - - async fn create_row(&self, row: RowMeta) -> FlowyResult<()> { - // let _ = self.modify(|grid| Ok(grid.create_row(row)?)).await?; - // self.cell_map.insert(row.id.clone(), row.clone()); - // let _ = self.kv_persistence.set(row)?; + async fn create_row(&self) -> FlowyResult<()> { + let row = RowMeta::new(&self.block_id, vec![]); + let _ = self.modify(|pad| Ok(pad.add_row(row)?)).await?; Ok(()) } pub async fn delete_rows(&self, ids: Vec) -> FlowyResult<()> { - // let _ = self.modify(|grid| Ok(grid.delete_rows(&ids)?)).await?; - // let _ = self.kv.batch_delete(ids)?; + let _ = self.modify(|pad| Ok(pad.delete_rows(&ids)?)).await?; Ok(()) } + pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { + let _ = self.modify(|pad| Ok(pad.update_row(changeset)?)).await?; + Ok(()) + } + + pub async fn get_rows(&self, row_ids: Vec) -> FlowyResult> { + let rows = self.meta_pad.read().await.get_rows(row_ids)?; + Ok(rows) + } + async fn modify(&self, f: F) -> FlowyResult<()> where F: for<'a> FnOnce(&'a mut GridBlockMetaPad) -> FlowyResult>, diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index 226426aeb7..340a260b09 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -1,7 +1,6 @@ mod util; pub mod cell_data; -pub mod grid_builder; pub mod grid_editor; pub mod grid_meta_editor; pub mod kv_persistence; diff --git a/frontend/rust-lib/flowy-grid/tests/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid_test.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/rust-lib/flowy-net/src/local_server/persistence.rs b/frontend/rust-lib/flowy-net/src/local_server/persistence.rs index 89e107e44f..525b487ce4 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/persistence.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/persistence.rs @@ -29,25 +29,25 @@ pub trait RevisionCloudStorage: Send + Sync { ) -> BoxResultFuture<(), CollaborateError>; } -pub(crate) struct LocalDocumentCloudPersistence { +pub(crate) struct LocalTextBlockCloudPersistence { storage: Arc, } -impl Debug for LocalDocumentCloudPersistence { +impl Debug for LocalTextBlockCloudPersistence { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str("LocalRevisionCloudPersistence") } } -impl std::default::Default for LocalDocumentCloudPersistence { +impl std::default::Default for LocalTextBlockCloudPersistence { fn default() -> Self { - LocalDocumentCloudPersistence { + LocalTextBlockCloudPersistence { storage: Arc::new(MemoryDocumentCloudStorage::default()), } } } -impl FolderCloudPersistence for LocalDocumentCloudPersistence { +impl FolderCloudPersistence for LocalTextBlockCloudPersistence { fn read_folder(&self, _user_id: &str, folder_id: &str) -> BoxResultFuture { let storage = self.storage.clone(); let folder_id = folder_id.to_owned(); @@ -110,8 +110,8 @@ impl FolderCloudPersistence for LocalDocumentCloudPersistence { } } -impl DocumentCloudPersistence for LocalDocumentCloudPersistence { - fn read_document(&self, doc_id: &str) -> BoxResultFuture { +impl TextBlockCloudPersistence for LocalTextBlockCloudPersistence { + fn read_text_block(&self, doc_id: &str) -> BoxResultFuture { let storage = self.storage.clone(); let doc_id = doc_id.to_owned(); Box::pin(async move { @@ -123,7 +123,7 @@ impl DocumentCloudPersistence for LocalDocumentCloudPersistence { }) } - fn create_document( + fn create_text_block( &self, doc_id: &str, repeated_revision: RepeatedRevisionPB, @@ -136,7 +136,7 @@ impl DocumentCloudPersistence for LocalDocumentCloudPersistence { }) } - fn read_document_revisions( + fn read_text_block_revisions( &self, doc_id: &str, rev_ids: Option>, @@ -150,7 +150,10 @@ impl DocumentCloudPersistence for LocalDocumentCloudPersistence { }) } - fn save_document_revisions(&self, repeated_revision: RepeatedRevisionPB) -> BoxResultFuture<(), CollaborateError> { + fn save_text_block_revisions( + &self, + repeated_revision: RepeatedRevisionPB, + ) -> BoxResultFuture<(), CollaborateError> { let storage = self.storage.clone(); Box::pin(async move { let _ = storage.set_revisions(repeated_revision).await?; @@ -158,7 +161,7 @@ impl DocumentCloudPersistence for LocalDocumentCloudPersistence { }) } - fn reset_document(&self, doc_id: &str, revisions: RepeatedRevisionPB) -> BoxResultFuture<(), CollaborateError> { + fn reset_text_block(&self, doc_id: &str, revisions: RepeatedRevisionPB) -> BoxResultFuture<(), CollaborateError> { let storage = self.storage.clone(); let doc_id = doc_id.to_owned(); Box::pin(async move { diff --git a/frontend/rust-lib/flowy-net/src/local_server/server.rs b/frontend/rust-lib/flowy-net/src/local_server/server.rs index b25bf9429f..646ca04e0f 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/server.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/server.rs @@ -1,4 +1,4 @@ -use crate::local_server::persistence::LocalDocumentCloudPersistence; +use crate::local_server::persistence::LocalTextBlockCloudPersistence; use async_stream::stream; use bytes::Bytes; use flowy_collaboration::{ @@ -38,7 +38,7 @@ impl LocalServer { client_ws_sender: mpsc::UnboundedSender, client_ws_receiver: broadcast::Sender, ) -> Self { - let persistence = Arc::new(LocalDocumentCloudPersistence::default()); + let persistence = Arc::new(LocalTextBlockCloudPersistence::default()); let doc_manager = Arc::new(ServerDocumentManager::new(persistence.clone())); let folder_manager = Arc::new(ServerFolderManager::new(persistence)); let stop_tx = RwLock::new(None); diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs index 6fea7bbe73..e0906cc7f1 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs @@ -1,7 +1,8 @@ use bytes::Bytes; use flowy_block::TextBlockManager; use flowy_collaboration::client_document::default::initial_quill_delta_string; -use flowy_collaboration::entities::revision::RepeatedRevision; +use flowy_collaboration::client_grid::make_default_grid; +use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; use flowy_folder::manager::{ViewDataProcessor, ViewDataProcessorMap}; @@ -12,7 +13,6 @@ use flowy_folder::{ manager::FolderManager, }; use flowy_grid::manager::GridManager; -use flowy_grid::services::grid_builder::make_default_grid; use flowy_net::ClientServerConfiguration; use flowy_net::{ http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect, @@ -140,9 +140,10 @@ impl ViewDataProcessor for TextBlockViewDataProcessor { FutureResult::new(async move { manager.init() }) } - fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FutureResult<(), FlowyError> { - let manager = self.0.clone(); + fn create_container(&self, user_id: &str, view_id: &str, delta_data: Bytes) -> FutureResult<(), FlowyError> { + let repeated_revision: RepeatedRevision = Revision::initial_revision(user_id, view_id, delta_data).into(); let view_id = view_id.to_string(); + let manager = self.0.clone(); FutureResult::new(async move { let _ = manager.create_block(view_id, repeated_revision).await?; Ok(()) @@ -177,12 +178,21 @@ impl ViewDataProcessor for TextBlockViewDataProcessor { }) } - fn default_view_data(&self, _view_id: &str) -> String { - initial_quill_delta_string() + fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult { + let user_id = user_id.to_string(); + let view_id = view_id.to_string(); + let manager = self.0.clone(); + FutureResult::new(async move { + let view_data = initial_quill_delta_string(); + let delta_data = Bytes::from(view_data.clone()); + let repeated_revision: RepeatedRevision = Revision::initial_revision(&user_id, &view_id, delta_data).into(); + let _ = manager.create_block(view_id, repeated_revision).await?; + Ok(view_data) + }) } fn data_type(&self) -> ViewDataType { - ViewDataType::Block + ViewDataType::TextBlock } } @@ -192,9 +202,10 @@ impl ViewDataProcessor for GridViewDataProcessor { FutureResult::new(async { Ok(()) }) } - fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FutureResult<(), FlowyError> { - let grid_manager = self.0.clone(); + fn create_container(&self, user_id: &str, view_id: &str, delta_data: Bytes) -> FutureResult<(), FlowyError> { + let repeated_revision: RepeatedRevision = Revision::initial_revision(user_id, view_id, delta_data).into(); let view_id = view_id.to_string(); + let grid_manager = self.0.clone(); FutureResult::new(async move { let _ = grid_manager.create_grid(view_id, repeated_revision).await?; Ok(()) @@ -229,8 +240,27 @@ impl ViewDataProcessor for GridViewDataProcessor { }) } - fn default_view_data(&self, view_id: &str) -> String { - make_default_grid(view_id, self.0.clone()) + fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult { + let info = make_default_grid(view_id); + let user_id = user_id.to_string(); + let view_id = view_id.to_string(); + let grid_manager = self.0.clone(); + + FutureResult::new(async move { + let grid_delta_data = Bytes::from(info.grid_delta.to_delta_str()); + let repeated_revision: RepeatedRevision = + Revision::initial_revision(&user_id, &view_id, grid_delta_data).into(); + let _ = grid_manager.create_grid(&view_id, repeated_revision).await?; + + let block_meta_delta_data = Bytes::from(info.grid_block_meta_delta.to_delta_str()); + let repeated_revision: RepeatedRevision = + Revision::initial_revision(&user_id, &info.block_id, block_meta_delta_data).into(); + let _ = grid_manager + .create_grid_block_meta(&info.block_id, repeated_revision) + .await?; + + Ok(info.grid_delta.to_delta_str()) + }) } fn data_type(&self) -> ViewDataType { diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs index ba4a0950af..4cd46058bf 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_meta_rev_impl.rs @@ -1,10 +1,10 @@ use crate::cache::disk::RevisionDiskCache; use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; -use crate::memory::RevisionMemoryCacheDelegate; + use bytes::Bytes; use diesel::{sql_types::Integer, update, SqliteConnection}; use flowy_collaboration::{ - entities::revision::{RevId, RevType, Revision, RevisionRange}, + entities::revision::{Revision, RevisionRange}, util::md5, }; use flowy_database::{ diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs index 385bc812c7..414bbb96c9 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/grid_rev_impl.rs @@ -1,10 +1,10 @@ use crate::cache::disk::RevisionDiskCache; use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; -use crate::memory::RevisionMemoryCacheDelegate; + use bytes::Bytes; use diesel::{sql_types::Integer, update, SqliteConnection}; use flowy_collaboration::{ - entities::revision::{RevId, RevType, Revision, RevisionRange}, + entities::revision::{Revision, RevisionRange}, util::md5, }; use flowy_database::{ diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs index e261f8d7ec..3a278afe36 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs @@ -8,8 +8,6 @@ pub use grid_meta_rev_impl::*; pub use grid_rev_impl::*; pub use text_rev_impl::*; -use crate::memory::RevisionMemoryCacheDelegate; -use diesel::SqliteConnection; use flowy_collaboration::entities::revision::{RevId, Revision, RevisionRange}; use flowy_error::FlowyResult; use std::fmt::Debug; diff --git a/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs b/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs index 0d780f824a..13a8298916 100644 --- a/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs +++ b/frontend/rust-lib/flowy-sync/src/cache/disk/text_rev_impl.rs @@ -1,10 +1,10 @@ use crate::cache::disk::RevisionDiskCache; use crate::disk::{RevisionChangeset, RevisionRecord, RevisionState}; -use crate::memory::RevisionMemoryCacheDelegate; + use bytes::Bytes; use diesel::{sql_types::Integer, update, SqliteConnection}; use flowy_collaboration::{ - entities::revision::{RevId, RevType, Revision, RevisionRange}, + entities::revision::{RevType, Revision, RevisionRange}, util::md5, }; use flowy_database::{ diff --git a/frontend/rust-lib/flowy-sync/src/rev_manager.rs b/frontend/rust-lib/flowy-sync/src/rev_manager.rs index ae26bbf68c..d0ed5240c8 100644 --- a/frontend/rust-lib/flowy-sync/src/rev_manager.rs +++ b/frontend/rust-lib/flowy-sync/src/rev_manager.rs @@ -7,7 +7,6 @@ use flowy_collaboration::{ }; use flowy_error::{FlowyError, FlowyResult}; use lib_infra::future::FutureResult; -use lib_ot::core::{Attributes, Delta}; use std::sync::Arc; pub trait RevisionCloudService: Send + Sync { diff --git a/frontend/rust-lib/flowy-test/src/helper.rs b/frontend/rust-lib/flowy-test/src/helper.rs index f28f7d35b0..83277b22c6 100644 --- a/frontend/rust-lib/flowy-test/src/helper.rs +++ b/frontend/rust-lib/flowy-test/src/helper.rs @@ -88,7 +88,7 @@ async fn create_view(sdk: &FlowySDKTest, app_id: &str) -> View { name: "View A".to_string(), desc: "".to_string(), thumbnail: Some("http://1.png".to_string()), - data_type: ViewDataType::Block, + data_type: ViewDataType::TextBlock, ext_data: "".to_string(), plugin_type: 0, }; diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index 0ca0d5ee03..1252f0d842 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -1,10 +1,11 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{GridBlockMeta, RowMeta, RowMetaChangeset, RowOrder}; +use flowy_grid_data_model::entities::{GridBlockMeta, RowMeta, RowMetaChangeset}; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use serde::{Deserialize, Serialize}; +use std::collections::HashMap; use std::sync::Arc; pub type GridBlockMetaDelta = PlainTextDelta; @@ -49,6 +50,25 @@ impl GridBlockMetaPad { }) } + pub fn get_rows(&self, row_ids: Vec) -> CollaborateResult> { + let row_map = self + .rows + .iter() + .map(|row| (&row.id, row.clone())) + .collect::>>(); + + Ok(row_ids + .iter() + .flat_map(|row_id| match row_map.get(row_id) { + None => { + tracing::error!("Can't find the row with id: {}", row_id); + None + } + Some(row) => Some((**row).clone()), + }) + .collect::>()) + } + pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { let row_id = changeset.row_id.clone(); self.modify_row(&row_id, |row| { @@ -123,12 +143,6 @@ impl GridBlockMetaPad { } } -fn json_from_grid(block_meta: &Arc) -> CollaborateResult { - let json = serde_json::to_string(block_meta) - .map_err(|err| internal_error(format!("Serialize grid to json str failed. {:?}", err)))?; - Ok(json) -} - pub struct GridBlockMetaChange { pub delta: GridBlockMetaDelta, /// md5: the md5 of the grid after applying the change. @@ -165,9 +179,8 @@ impl std::default::Default for GridBlockMetaPad { #[cfg(test)] mod tests { - use crate::client_grid::{GridBlockMetaDelta, GridMetaPad}; + use crate::client_grid::{GridBlockMetaDelta, GridBlockMetaPad}; use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset}; - use std::str::FromStr; #[test] fn block_meta_add_row() { @@ -227,7 +240,7 @@ mod tests { cell_by_field_id: Default::default(), }; - let _ = pad.add_row(row.clone()).unwrap().unwrap(); + let _ = pad.add_row(row).unwrap().unwrap(); let change = pad.update_row(changeset).unwrap().unwrap(); assert_eq!( @@ -241,8 +254,8 @@ mod tests { ); } - fn test_pad() -> GridMetaPad { + fn test_pad() -> GridBlockMetaPad { let delta = GridBlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap(); - GridMetaPad::from_delta(delta).unwrap() + GridBlockMetaPad::from_delta(delta).unwrap() } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs new file mode 100644 index 0000000000..dbc41e28ae --- /dev/null +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -0,0 +1,114 @@ +use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBlockMetaDelta, GridMetaDelta}; +use crate::errors::{CollaborateError, CollaborateResult}; +use flowy_grid_data_model::entities::{Field, FieldType, GridBlock, GridBlockMeta, GridMeta, RowMeta}; + +pub struct GridBuilder { + grid_id: String, + fields: Vec, + grid_block: GridBlock, + grid_block_meta: GridBlockMeta, +} + +impl GridBuilder { + pub fn new(grid_id: &str) -> Self { + let grid_block = GridBlock::new(); + let grid_block_meta = GridBlockMeta { + block_id: grid_block.id.clone(), + rows: vec![], + }; + + Self { + grid_id: grid_id.to_owned(), + fields: vec![], + grid_block, + grid_block_meta, + } + } + + pub fn add_field(mut self, name: &str, desc: &str, field_type: FieldType) -> Self { + let field = Field::new(name, desc, field_type); + self.fields.push(field); + self + } + + pub fn add_empty_row(mut self) -> Self { + let row = RowMeta::new(&self.grid_block.id, vec![]); + self.grid_block_meta.rows.push(row); + self + } + + pub fn build(self) -> CollaborateResult { + let block_id = self.grid_block.id.clone(); + let grid_meta = GridMeta { + grid_id: self.grid_id, + fields: self.fields, + blocks: vec![self.grid_block], + }; + // let _ = check_rows(&self.fields, &self.rows)?; + let grid_delta = make_grid_delta(&grid_meta); + let grid_block_meta_delta = make_block_meta_delta(&self.grid_block_meta); + Ok(BuildGridInfo { + grid_delta, + block_id, + grid_block_meta_delta, + }) + } +} + +pub struct BuildGridInfo { + pub grid_delta: GridMetaDelta, + pub block_id: String, + pub grid_block_meta_delta: GridBlockMetaDelta, +} + +#[allow(dead_code)] +fn check_rows(fields: &[Field], rows: &[RowMeta]) -> CollaborateResult<()> { + let field_ids = fields.iter().map(|field| &field.id).collect::>(); + for row in rows { + let cell_field_ids = row.cell_by_field_id.keys().into_iter().collect::>(); + if cell_field_ids != field_ids { + let msg = format!("{:?} contains invalid cells", row); + return Err(CollaborateError::internal().context(msg)); + } + } + Ok(()) +} + +pub fn make_default_grid(grid_id: &str) -> BuildGridInfo { + GridBuilder::new(grid_id) + .add_field("Name", "", FieldType::RichText) + .add_field("Tags", "", FieldType::SingleSelect) + .add_empty_row() + .add_empty_row() + .add_empty_row() + .build() + .unwrap() +} + +#[cfg(test)] +mod tests { + use crate::client_grid::GridBuilder; + use flowy_grid_data_model::entities::{FieldType, GridBlockMeta, GridMeta}; + + #[test] + fn create_default_grid_test() { + let info = GridBuilder::new("1") + .add_field("Name", "", FieldType::RichText) + .add_field("Tags", "", FieldType::SingleSelect) + .add_empty_row() + .add_empty_row() + .add_empty_row() + .build() + .unwrap(); + + let grid_meta: GridMeta = serde_json::from_str(&info.grid_delta.to_str().unwrap()).unwrap(); + assert_eq!(grid_meta.fields.len(), 2); + assert_eq!(grid_meta.blocks.len(), 1); + + let grid_block_meta: GridBlockMeta = + serde_json::from_str(&info.grid_block_meta_delta.to_str().unwrap()).unwrap(); + assert_eq!(grid_block_meta.rows.len(), 3); + + assert_eq!(grid_meta.blocks[0].id, grid_block_meta.block_id); + } +} diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 6e04107e44..5b99afd9c2 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -2,24 +2,23 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use flowy_grid_data_model::entities::{ - Field, FieldChangeset, FieldOrder, Grid, GridBlock, GridBlockChangeset, GridMeta, RepeatedField, - RepeatedFieldOrder, RowMeta, RowOrder, + Field, FieldChangeset, GridBlock, GridBlockChangeset, GridMeta, RepeatedField, RepeatedFieldOrder, }; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use std::collections::HashMap; use std::sync::Arc; -pub type GridDelta = PlainTextDelta; +pub type GridMetaDelta = PlainTextDelta; pub type GridDeltaBuilder = PlainTextDeltaBuilder; pub struct GridMetaPad { pub(crate) grid_meta: Arc, - pub(crate) delta: GridDelta, + pub(crate) delta: GridMetaDelta, } impl GridMetaPad { - pub fn from_delta(delta: GridDelta) -> CollaborateResult { + pub fn from_delta(delta: GridMetaDelta) -> CollaborateResult { let s = delta.to_str()?; let grid: GridMeta = serde_json::from_str(&s) .map_err(|e| CollaborateError::internal().context(format!("Deserialize delta to grid failed: {}", e)))?; @@ -31,7 +30,7 @@ impl GridMetaPad { } pub fn from_revisions(_grid_id: &str, revisions: Vec) -> CollaborateResult { - let grid_delta: GridDelta = make_delta_from_revisions::(revisions)?; + let grid_delta: GridMetaDelta = make_delta_from_revisions::(revisions)?; Self::from_delta(grid_delta) } @@ -64,7 +63,7 @@ impl GridMetaPad { .iter() .flat_map(|field_order| match field_by_field_id.get(&field_order.field_id) { None => { - tracing::error!("Can't find the field with {}", field_order.field_id); + tracing::error!("Can't find the field with id: {}", field_order.field_id); None } Some(field) => Some((*field).clone()), @@ -123,6 +122,10 @@ impl GridMetaPad { }) } + pub fn get_blocks(&self) -> Vec { + self.grid_meta.blocks.clone() + } + pub fn update_block(&mut self, change: GridBlockChangeset) -> CollaborateResult> { let block_id = change.block_id.clone(); self.modify_block(&block_id, |block| { @@ -204,12 +207,12 @@ fn json_from_grid(grid: &Arc) -> CollaborateResult { } pub struct GridChange { - pub delta: GridDelta, + pub delta: GridMetaDelta, /// md5: the md5 of the grid after applying the change. pub md5: String, } -pub fn make_grid_delta(grid_meta: &GridMeta) -> GridDelta { +pub fn make_grid_delta(grid_meta: &GridMeta) -> GridMetaDelta { let json = serde_json::to_string(&grid_meta).unwrap(); PlainTextDeltaBuilder::new().insert(&json).build() } diff --git a/shared-lib/flowy-collaboration/src/client_grid/mod.rs b/shared-lib/flowy-collaboration/src/client_grid/mod.rs index 8ecb671968..5fbaa170b4 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/mod.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/mod.rs @@ -1,5 +1,7 @@ mod block_pad; +mod grid_builder; mod grid_pad; pub use block_pad::*; +pub use grid_builder::*; pub use grid_pad::*; diff --git a/shared-lib/flowy-collaboration/src/server_document/document_manager.rs b/shared-lib/flowy-collaboration/src/server_document/document_manager.rs index 8a5b5f7304..3232f0e9ca 100644 --- a/shared-lib/flowy-collaboration/src/server_document/document_manager.rs +++ b/shared-lib/flowy-collaboration/src/server_document/document_manager.rs @@ -17,41 +17,42 @@ use tokio::{ task::spawn_blocking, }; -pub trait DocumentCloudPersistence: Send + Sync + Debug { - fn read_document(&self, doc_id: &str) -> BoxResultFuture; +pub trait TextBlockCloudPersistence: Send + Sync + Debug { + fn read_text_block(&self, doc_id: &str) -> BoxResultFuture; - fn create_document( + fn create_text_block( &self, doc_id: &str, repeated_revision: RepeatedRevisionPB, ) -> BoxResultFuture, CollaborateError>; - fn read_document_revisions( + fn read_text_block_revisions( &self, doc_id: &str, rev_ids: Option>, ) -> BoxResultFuture, CollaborateError>; - fn save_document_revisions(&self, repeated_revision: RepeatedRevisionPB) -> BoxResultFuture<(), CollaborateError>; + fn save_text_block_revisions(&self, repeated_revision: RepeatedRevisionPB) + -> BoxResultFuture<(), CollaborateError>; - fn reset_document( + fn reset_text_block( &self, doc_id: &str, repeated_revision: RepeatedRevisionPB, ) -> BoxResultFuture<(), CollaborateError>; } -impl RevisionSyncPersistence for Arc { +impl RevisionSyncPersistence for Arc { fn read_revisions( &self, object_id: &str, rev_ids: Option>, ) -> BoxResultFuture, CollaborateError> { - (**self).read_document_revisions(object_id, rev_ids) + (**self).read_text_block_revisions(object_id, rev_ids) } fn save_revisions(&self, repeated_revision: RepeatedRevisionPB) -> BoxResultFuture<(), CollaborateError> { - (**self).save_document_revisions(repeated_revision) + (**self).save_text_block_revisions(repeated_revision) } fn reset_object( @@ -59,17 +60,17 @@ impl RevisionSyncPersistence for Arc { object_id: &str, repeated_revision: RepeatedRevisionPB, ) -> BoxResultFuture<(), CollaborateError> { - (**self).reset_document(object_id, repeated_revision) + (**self).reset_text_block(object_id, repeated_revision) } } pub struct ServerDocumentManager { document_handlers: Arc>>>, - persistence: Arc, + persistence: Arc, } impl ServerDocumentManager { - pub fn new(persistence: Arc) -> Self { + pub fn new(persistence: Arc) -> Self { Self { document_handlers: Arc::new(RwLock::new(HashMap::new())), persistence, @@ -151,7 +152,7 @@ impl ServerDocumentManager { } let mut write_guard = self.document_handlers.write().await; - match self.persistence.read_document(doc_id).await { + match self.persistence.read_text_block(doc_id).await { Ok(doc) => { let handler = self.create_document_handler(doc).await.map_err(internal_error).unwrap(); write_guard.insert(doc_id.to_owned(), handler.clone()); @@ -168,7 +169,7 @@ impl ServerDocumentManager { doc_id: &str, repeated_revision: RepeatedRevisionPB, ) -> Result, CollaborateError> { - match self.persistence.create_document(doc_id, repeated_revision).await? { + match self.persistence.create_text_block(doc_id, repeated_revision).await? { None => Err(CollaborateError::internal().context("Create document info from revisions failed")), Some(doc) => { let handler = self.create_document_handler(doc).await?; @@ -205,7 +206,7 @@ struct OpenDocumentHandler { } impl OpenDocumentHandler { - fn new(doc: TextBlockInfo, persistence: Arc) -> Result { + fn new(doc: TextBlockInfo, persistence: Arc) -> Result { let doc_id = doc.block_id.clone(); let (sender, receiver) = mpsc::channel(1000); let users = DashMap::new(); diff --git a/shared-lib/flowy-folder-data-model/src/entities/view.rs b/shared-lib/flowy-folder-data-model/src/entities/view.rs index 307850d396..8d6ac05406 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/view.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/view.rs @@ -83,24 +83,24 @@ impl std::convert::From for Trash { #[derive(Eq, PartialEq, Hash, Debug, ProtoBuf_Enum, Clone, Serialize_repr, Deserialize_repr)] #[repr(u8)] pub enum ViewDataType { - Block = 0, + TextBlock = 0, Grid = 1, } impl std::default::Default for ViewDataType { fn default() -> Self { - ViewDataType::Block + ViewDataType::TextBlock } } impl std::convert::From for ViewDataType { fn from(val: i32) -> Self { match val { - 0 => ViewDataType::Block, + 0 => ViewDataType::TextBlock, 1 => ViewDataType::Grid, _ => { log::error!("Invalid view type: {}", val); - ViewDataType::Block + ViewDataType::TextBlock } } } diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs index 26173acfaf..bb38b794f2 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs +++ b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs @@ -165,7 +165,7 @@ impl View { self.data_type } pub fn clear_data_type(&mut self) { - self.data_type = ViewDataType::Block; + self.data_type = ViewDataType::TextBlock; } // Param is passed by value, moved @@ -409,7 +409,7 @@ impl ::protobuf::Message for View { if !self.desc.is_empty() { my_size += ::protobuf::rt::string_size(4, &self.desc); } - if self.data_type != ViewDataType::Block { + if self.data_type != ViewDataType::TextBlock { my_size += ::protobuf::rt::enum_size(5, self.data_type); } if self.version != 0 { @@ -452,7 +452,7 @@ impl ::protobuf::Message for View { if !self.desc.is_empty() { os.write_string(4, &self.desc)?; } - if self.data_type != ViewDataType::Block { + if self.data_type != ViewDataType::TextBlock { os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?; } if self.version != 0 { @@ -596,7 +596,7 @@ impl ::protobuf::Clear for View { self.belong_to_id.clear(); self.name.clear(); self.desc.clear(); - self.data_type = ViewDataType::Block; + self.data_type = ViewDataType::TextBlock; self.version = 0; self.belongings.clear(); self.modified_time = 0; @@ -952,7 +952,7 @@ impl CreateViewPayload { self.data_type } pub fn clear_data_type(&mut self) { - self.data_type = ViewDataType::Block; + self.data_type = ViewDataType::TextBlock; } // Param is passed by value, moved @@ -1060,7 +1060,7 @@ impl ::protobuf::Message for CreateViewPayload { if !self.desc.is_empty() { my_size += ::protobuf::rt::string_size(3, &self.desc); } - if self.data_type != ViewDataType::Block { + if self.data_type != ViewDataType::TextBlock { my_size += ::protobuf::rt::enum_size(5, self.data_type); } if !self.ext_data.is_empty() { @@ -1091,7 +1091,7 @@ impl ::protobuf::Message for CreateViewPayload { if !self.desc.is_empty() { os.write_string(3, &self.desc)?; } - if self.data_type != ViewDataType::Block { + if self.data_type != ViewDataType::TextBlock { os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?; } if !self.ext_data.is_empty() { @@ -1200,7 +1200,7 @@ impl ::protobuf::Clear for CreateViewPayload { self.name.clear(); self.desc.clear(); self.one_of_thumbnail = ::std::option::Option::None; - self.data_type = ViewDataType::Block; + self.data_type = ViewDataType::TextBlock; self.ext_data.clear(); self.plugin_type = 0; self.unknown_fields.clear(); @@ -1358,7 +1358,7 @@ impl CreateViewParams { self.data_type } pub fn clear_data_type(&mut self) { - self.data_type = ViewDataType::Block; + self.data_type = ViewDataType::TextBlock; } // Param is passed by value, moved @@ -1524,7 +1524,7 @@ impl ::protobuf::Message for CreateViewParams { if !self.thumbnail.is_empty() { my_size += ::protobuf::rt::string_size(4, &self.thumbnail); } - if self.data_type != ViewDataType::Block { + if self.data_type != ViewDataType::TextBlock { my_size += ::protobuf::rt::enum_size(5, self.data_type); } if !self.ext_data.is_empty() { @@ -1557,7 +1557,7 @@ impl ::protobuf::Message for CreateViewParams { if !self.thumbnail.is_empty() { os.write_string(4, &self.thumbnail)?; } - if self.data_type != ViewDataType::Block { + if self.data_type != ViewDataType::TextBlock { os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?; } if !self.ext_data.is_empty() { @@ -1675,7 +1675,7 @@ impl ::protobuf::Clear for CreateViewParams { self.name.clear(); self.desc.clear(); self.thumbnail.clear(); - self.data_type = ViewDataType::Block; + self.data_type = ViewDataType::TextBlock; self.ext_data.clear(); self.view_id.clear(); self.data.clear(); @@ -2821,7 +2821,7 @@ impl ::protobuf::reflect::ProtobufValue for UpdateViewParams { #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum ViewDataType { - Block = 0, + TextBlock = 0, Grid = 1, } @@ -2832,7 +2832,7 @@ impl ::protobuf::ProtobufEnum for ViewDataType { fn from_i32(value: i32) -> ::std::option::Option { match value { - 0 => ::std::option::Option::Some(ViewDataType::Block), + 0 => ::std::option::Option::Some(ViewDataType::TextBlock), 1 => ::std::option::Option::Some(ViewDataType::Grid), _ => ::std::option::Option::None } @@ -2840,7 +2840,7 @@ impl ::protobuf::ProtobufEnum for ViewDataType { fn values() -> &'static [Self] { static values: &'static [ViewDataType] = &[ - ViewDataType::Block, + ViewDataType::TextBlock, ViewDataType::Grid, ]; values @@ -2859,7 +2859,7 @@ impl ::std::marker::Copy for ViewDataType { impl ::std::default::Default for ViewDataType { fn default() -> Self { - ViewDataType::Block + ViewDataType::TextBlock } } @@ -2904,8 +2904,8 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\ \x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\ \x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\ - \x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail*#\n\x0cVi\ - ewDataType\x12\t\n\x05Block\x10\0\x12\x08\n\x04Grid\x10\x01b\x06proto3\ + \x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail*'\n\x0cVi\ + ewDataType\x12\r\n\tTextBlock\x10\0\x12\x08\n\x04Grid\x10\x01b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto index 2a471bc53f..9d51c50263 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto +++ b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto @@ -56,6 +56,6 @@ message UpdateViewParams { oneof one_of_thumbnail { string thumbnail = 4; }; } enum ViewDataType { - Block = 0; + TextBlock = 0; Grid = 1; } diff --git a/shared-lib/flowy-folder-data-model/src/user_default.rs b/shared-lib/flowy-folder-data-model/src/user_default.rs index 198953a61f..ff3161d89b 100644 --- a/shared-lib/flowy-folder-data-model/src/user_default.rs +++ b/shared-lib/flowy-folder-data-model/src/user_default.rs @@ -49,7 +49,7 @@ fn create_default_view(app_id: String, time: chrono::DateTime) -> View { let view_id = uuid::Uuid::new_v4(); let name = "Read me".to_string(); let desc = "".to_string(); - let data_type = ViewDataType::Block; + let data_type = ViewDataType::TextBlock; View { id: view_id.to_string(), diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index f6691456c8..b5cdc96e31 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -30,6 +30,15 @@ pub struct GridBlock { pub row_count: i32, } +impl GridBlock { + pub fn new() -> Self { + GridBlock { + id: uuid::Uuid::new_v4().to_string(), + ..Default::default() + } + } +} + pub struct GridBlockChangeset { pub block_id: String, pub start_row_index: Option, @@ -73,9 +82,9 @@ pub struct Field { } impl Field { - pub fn new(id: &str, name: &str, desc: &str, field_type: FieldType) -> Self { + pub fn new(name: &str, desc: &str, field_type: FieldType) -> Self { Self { - id: id.to_owned(), + id: uuid::Uuid::new_v4().to_string(), name: name.to_string(), desc: desc.to_string(), field_type, @@ -224,14 +233,14 @@ pub struct RowMeta { } impl RowMeta { - pub fn new(id: &str, block_id: &str, cells: Vec) -> Self { + pub fn new(block_id: &str, cells: Vec) -> Self { let cell_by_field_id = cells .into_iter() .map(|cell| (cell.id.clone(), cell)) .collect::>(); Self { - id: id.to_owned(), + id: uuid::Uuid::new_v4().to_string(), block_id: block_id.to_owned(), cell_by_field_id, height: DEFAULT_ROW_HEIGHT, diff --git a/shared-lib/flowy-grid-data-model/tests/serde_test.rs b/shared-lib/flowy-grid-data-model/tests/serde_test.rs index 2d1495e811..49780e2a52 100644 --- a/shared-lib/flowy-grid-data-model/tests/serde_test.rs +++ b/shared-lib/flowy-grid-data-model/tests/serde_test.rs @@ -32,7 +32,9 @@ fn grid_default_serde_test() { } fn create_field(field_id: &str) -> Field { - Field::new(field_id, "Text Field", "", FieldType::RichText) + let mut field = Field::new("Text Field", "", FieldType::RichText); + field.id = field_id.to_string(); + field } #[allow(dead_code)] From 1e6d82c0ec158b772cf82e332705ede92c83626e Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 12 Mar 2022 21:06:15 +0800 Subject: [PATCH 14/28] chore: add field builder --- .../lib/protobuf/flowy-grid/protobuf.dart | 2 +- .../protobuf/flowy-grid/type_options.pb.dart | 458 ++++++++++++++++++ .../flowy-grid/type_options.pbenum.dart | 62 +++ .../flowy-grid/type_options.pbjson.dart | 125 +++++ .../flowy-grid/type_options.pbserver.dart | 9 + frontend/rust-lib/Cargo.lock | 2 + frontend/rust-lib/flowy-block/src/editor.rs | 14 +- frontend/rust-lib/flowy-block/src/queue.rs | 6 +- .../flowy-block/tests/document/mod.rs | 4 +- .../document/{edit_script.rs => script.rs} | 10 +- .../{document_test.rs => text_block_test.rs} | 34 +- .../src/services/folder_editor.rs | 2 +- .../tests/workspace/folder_test.rs | 17 +- .../flowy-folder/tests/workspace/helper.rs | 212 -------- .../flowy-folder/tests/workspace/main.rs | 1 - .../flowy-folder/tests/workspace/script.rs | 250 +++++++++- frontend/rust-lib/flowy-grid/Cargo.toml | 7 +- frontend/rust-lib/flowy-grid/Flowy.toml | 2 +- frontend/rust-lib/flowy-grid/src/lib.rs | 1 + frontend/rust-lib/flowy-grid/src/macros.rs | 35 +- frontend/rust-lib/flowy-grid/src/manager.rs | 2 +- .../flowy-grid/src/protobuf/model/mod.rs | 4 +- .../model/{cell_data.rs => type_options.rs} | 167 +++---- .../{cell_data.proto => type_options.proto} | 8 +- .../src/services/field/cell_stringify.rs | 34 ++ .../src/services/field/field_builder.rs | 217 +++++++++ .../flowy-grid/src/services/field/mod.rs | 7 + .../{cell_data.rs => field/type_options.rs} | 175 +++---- .../flowy-grid/src/services/grid_editor.rs | 15 +- .../src/services/grid_meta_editor.rs | 2 +- .../rust-lib/flowy-grid/src/services/mod.rs | 3 +- .../flowy-grid/src/services/stringify.rs | 29 -- .../rust-lib/flowy-grid/src/services/util.rs | 10 +- frontend/rust-lib/flowy-grid/src/util.rs | 30 ++ .../flowy-grid/tests/grid/grid_test.rs | 16 + .../rust-lib/flowy-grid/tests/grid/mod.rs | 2 + .../rust-lib/flowy-grid/tests/grid/script.rs | 75 +++ .../rust-lib/flowy-grid/tests/grid_test.rs | 0 frontend/rust-lib/flowy-grid/tests/main.rs | 1 + .../flowy-sdk/src/deps_resolve/folder_deps.rs | 2 +- .../rust-lib/flowy-sync/src/rev_manager.rs | 4 +- frontend/rust-lib/flowy-test/src/helper.rs | 19 +- .../src/client_grid/grid_builder.rs | 20 +- .../src/entities/meta.rs | 19 +- 44 files changed, 1545 insertions(+), 569 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbserver.dart rename frontend/rust-lib/flowy-block/tests/document/{edit_script.rs => script.rs} (91%) rename frontend/rust-lib/flowy-block/tests/document/{document_test.rs => text_block_test.rs} (69%) delete mode 100644 frontend/rust-lib/flowy-folder/tests/workspace/helper.rs rename frontend/rust-lib/flowy-grid/src/protobuf/model/{cell_data.rs => type_options.rs} (91%) rename frontend/rust-lib/flowy-grid/src/protobuf/proto/{cell_data.proto => type_options.proto} (87%) create mode 100644 frontend/rust-lib/flowy-grid/src/services/field/cell_stringify.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/field/mod.rs rename frontend/rust-lib/flowy-grid/src/services/{cell_data.rs => field/type_options.rs} (65%) delete mode 100644 frontend/rust-lib/flowy-grid/src/services/stringify.rs create mode 100644 frontend/rust-lib/flowy-grid/src/util.rs create mode 100644 frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs create mode 100644 frontend/rust-lib/flowy-grid/tests/grid/mod.rs create mode 100644 frontend/rust-lib/flowy-grid/tests/grid/script.rs delete mode 100644 frontend/rust-lib/flowy-grid/tests/grid_test.rs create mode 100644 frontend/rust-lib/flowy-grid/tests/main.rs diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart index 39a722893a..b7eb77d660 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart @@ -1,3 +1,3 @@ // Auto-generated, do not edit -export './cell_data.pb.dart'; +export './type_options.pb.dart'; export './event_map.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pb.dart new file mode 100644 index 0000000000..152eef0c74 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pb.dart @@ -0,0 +1,458 @@ +/// +// Generated code. Do not modify. +// source: type_options.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'type_options.pbenum.dart'; + +export 'type_options.pbenum.dart'; + +class RichTextDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RichTextDescription', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'format') + ..hasRequiredFields = false + ; + + RichTextDescription._() : super(); + factory RichTextDescription({ + $core.String? format, + }) { + final _result = create(); + if (format != null) { + _result.format = format; + } + return _result; + } + factory RichTextDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RichTextDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RichTextDescription clone() => RichTextDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RichTextDescription copyWith(void Function(RichTextDescription) updates) => super.copyWith((message) => updates(message as RichTextDescription)) as RichTextDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RichTextDescription create() => RichTextDescription._(); + RichTextDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RichTextDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RichTextDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get format => $_getSZ(0); + @$pb.TagNumber(1) + set format($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasFormat() => $_has(0); + @$pb.TagNumber(1) + void clearFormat() => clearField(1); +} + +class CheckboxDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CheckboxDescription', createEmptyInstance: create) + ..aOB(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'isSelected') + ..hasRequiredFields = false + ; + + CheckboxDescription._() : super(); + factory CheckboxDescription({ + $core.bool? isSelected, + }) { + final _result = create(); + if (isSelected != null) { + _result.isSelected = isSelected; + } + return _result; + } + factory CheckboxDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CheckboxDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CheckboxDescription clone() => CheckboxDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CheckboxDescription copyWith(void Function(CheckboxDescription) updates) => super.copyWith((message) => updates(message as CheckboxDescription)) as CheckboxDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CheckboxDescription create() => CheckboxDescription._(); + CheckboxDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CheckboxDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CheckboxDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.bool get isSelected => $_getBF(0); + @$pb.TagNumber(1) + set isSelected($core.bool v) { $_setBool(0, v); } + @$pb.TagNumber(1) + $core.bool hasIsSelected() => $_has(0); + @$pb.TagNumber(1) + void clearIsSelected() => clearField(1); +} + +class DateDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'DateDescription', createEmptyInstance: create) + ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dateFormat', $pb.PbFieldType.OE, defaultOrMaker: DateFormat.Local, valueOf: DateFormat.valueOf, enumValues: DateFormat.values) + ..e(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'timeFormat', $pb.PbFieldType.OE, defaultOrMaker: TimeFormat.TwelveHour, valueOf: TimeFormat.valueOf, enumValues: TimeFormat.values) + ..hasRequiredFields = false + ; + + DateDescription._() : super(); + factory DateDescription({ + DateFormat? dateFormat, + TimeFormat? timeFormat, + }) { + final _result = create(); + if (dateFormat != null) { + _result.dateFormat = dateFormat; + } + if (timeFormat != null) { + _result.timeFormat = timeFormat; + } + return _result; + } + factory DateDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory DateDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + DateDescription clone() => DateDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + DateDescription copyWith(void Function(DateDescription) updates) => super.copyWith((message) => updates(message as DateDescription)) as DateDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static DateDescription create() => DateDescription._(); + DateDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static DateDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static DateDescription? _defaultInstance; + + @$pb.TagNumber(1) + DateFormat get dateFormat => $_getN(0); + @$pb.TagNumber(1) + set dateFormat(DateFormat v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasDateFormat() => $_has(0); + @$pb.TagNumber(1) + void clearDateFormat() => clearField(1); + + @$pb.TagNumber(2) + TimeFormat get timeFormat => $_getN(1); + @$pb.TagNumber(2) + set timeFormat(TimeFormat v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasTimeFormat() => $_has(1); + @$pb.TagNumber(2) + void clearTimeFormat() => clearField(2); +} + +class SingleSelectDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SingleSelectDescription', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'options', $pb.PbFieldType.PM, subBuilder: SelectOption.create) + ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'disableColor') + ..hasRequiredFields = false + ; + + SingleSelectDescription._() : super(); + factory SingleSelectDescription({ + $core.Iterable? options, + $core.bool? disableColor, + }) { + final _result = create(); + if (options != null) { + _result.options.addAll(options); + } + if (disableColor != null) { + _result.disableColor = disableColor; + } + return _result; + } + factory SingleSelectDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory SingleSelectDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SingleSelectDescription clone() => SingleSelectDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SingleSelectDescription copyWith(void Function(SingleSelectDescription) updates) => super.copyWith((message) => updates(message as SingleSelectDescription)) as SingleSelectDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static SingleSelectDescription create() => SingleSelectDescription._(); + SingleSelectDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SingleSelectDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static SingleSelectDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get options => $_getList(0); + + @$pb.TagNumber(2) + $core.bool get disableColor => $_getBF(1); + @$pb.TagNumber(2) + set disableColor($core.bool v) { $_setBool(1, v); } + @$pb.TagNumber(2) + $core.bool hasDisableColor() => $_has(1); + @$pb.TagNumber(2) + void clearDisableColor() => clearField(2); +} + +class MultiSelectDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'MultiSelectDescription', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'options', $pb.PbFieldType.PM, subBuilder: SelectOption.create) + ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'disableColor') + ..hasRequiredFields = false + ; + + MultiSelectDescription._() : super(); + factory MultiSelectDescription({ + $core.Iterable? options, + $core.bool? disableColor, + }) { + final _result = create(); + if (options != null) { + _result.options.addAll(options); + } + if (disableColor != null) { + _result.disableColor = disableColor; + } + return _result; + } + factory MultiSelectDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory MultiSelectDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + MultiSelectDescription clone() => MultiSelectDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + MultiSelectDescription copyWith(void Function(MultiSelectDescription) updates) => super.copyWith((message) => updates(message as MultiSelectDescription)) as MultiSelectDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static MultiSelectDescription create() => MultiSelectDescription._(); + MultiSelectDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static MultiSelectDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static MultiSelectDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get options => $_getList(0); + + @$pb.TagNumber(2) + $core.bool get disableColor => $_getBF(1); + @$pb.TagNumber(2) + set disableColor($core.bool v) { $_setBool(1, v); } + @$pb.TagNumber(2) + $core.bool hasDisableColor() => $_has(1); + @$pb.TagNumber(2) + void clearDisableColor() => clearField(2); +} + +class SelectOption extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOption', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'color') + ..hasRequiredFields = false + ; + + SelectOption._() : super(); + factory SelectOption({ + $core.String? id, + $core.String? name, + $core.String? color, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (name != null) { + _result.name = name; + } + if (color != null) { + _result.color = color; + } + return _result; + } + factory SelectOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory SelectOption.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SelectOption clone() => SelectOption()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SelectOption copyWith(void Function(SelectOption) updates) => super.copyWith((message) => updates(message as SelectOption)) as SelectOption; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static SelectOption create() => SelectOption._(); + SelectOption createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SelectOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static SelectOption? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get name => $_getSZ(1); + @$pb.TagNumber(2) + set name($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasName() => $_has(1); + @$pb.TagNumber(2) + void clearName() => clearField(2); + + @$pb.TagNumber(3) + $core.String get color => $_getSZ(2); + @$pb.TagNumber(3) + set color($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasColor() => $_has(2); + @$pb.TagNumber(3) + void clearColor() => clearField(3); +} + +class NumberDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'NumberDescription', createEmptyInstance: create) + ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'money', $pb.PbFieldType.OE, defaultOrMaker: MoneySymbol.CNY, valueOf: MoneySymbol.valueOf, enumValues: MoneySymbol.values) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scale', $pb.PbFieldType.OU3) + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'symbol') + ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signPositive') + ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..hasRequiredFields = false + ; + + NumberDescription._() : super(); + factory NumberDescription({ + MoneySymbol? money, + $core.int? scale, + $core.String? symbol, + $core.bool? signPositive, + $core.String? name, + }) { + final _result = create(); + if (money != null) { + _result.money = money; + } + if (scale != null) { + _result.scale = scale; + } + if (symbol != null) { + _result.symbol = symbol; + } + if (signPositive != null) { + _result.signPositive = signPositive; + } + if (name != null) { + _result.name = name; + } + return _result; + } + factory NumberDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory NumberDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + NumberDescription clone() => NumberDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + NumberDescription copyWith(void Function(NumberDescription) updates) => super.copyWith((message) => updates(message as NumberDescription)) as NumberDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static NumberDescription create() => NumberDescription._(); + NumberDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static NumberDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static NumberDescription? _defaultInstance; + + @$pb.TagNumber(1) + MoneySymbol get money => $_getN(0); + @$pb.TagNumber(1) + set money(MoneySymbol v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasMoney() => $_has(0); + @$pb.TagNumber(1) + void clearMoney() => clearField(1); + + @$pb.TagNumber(2) + $core.int get scale => $_getIZ(1); + @$pb.TagNumber(2) + set scale($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasScale() => $_has(1); + @$pb.TagNumber(2) + void clearScale() => clearField(2); + + @$pb.TagNumber(3) + $core.String get symbol => $_getSZ(2); + @$pb.TagNumber(3) + set symbol($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasSymbol() => $_has(2); + @$pb.TagNumber(3) + void clearSymbol() => clearField(3); + + @$pb.TagNumber(4) + $core.bool get signPositive => $_getBF(3); + @$pb.TagNumber(4) + set signPositive($core.bool v) { $_setBool(3, v); } + @$pb.TagNumber(4) + $core.bool hasSignPositive() => $_has(3); + @$pb.TagNumber(4) + void clearSignPositive() => clearField(4); + + @$pb.TagNumber(5) + $core.String get name => $_getSZ(4); + @$pb.TagNumber(5) + set name($core.String v) { $_setString(4, v); } + @$pb.TagNumber(5) + $core.bool hasName() => $_has(4); + @$pb.TagNumber(5) + void clearName() => clearField(5); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbenum.dart new file mode 100644 index 0000000000..c3815cf5e1 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbenum.dart @@ -0,0 +1,62 @@ +/// +// Generated code. Do not modify. +// source: type_options.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +// ignore_for_file: UNDEFINED_SHOWN_NAME +import 'dart:core' as $core; +import 'package:protobuf/protobuf.dart' as $pb; + +class DateFormat extends $pb.ProtobufEnum { + static const DateFormat Local = DateFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Local'); + static const DateFormat US = DateFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'US'); + static const DateFormat ISO = DateFormat._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ISO'); + static const DateFormat Friendly = DateFormat._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Friendly'); + + static const $core.List values = [ + Local, + US, + ISO, + Friendly, + ]; + + static final $core.Map<$core.int, DateFormat> _byValue = $pb.ProtobufEnum.initByValue(values); + static DateFormat? valueOf($core.int value) => _byValue[value]; + + const DateFormat._($core.int v, $core.String n) : super(v, n); +} + +class TimeFormat extends $pb.ProtobufEnum { + static const TimeFormat TwelveHour = TimeFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TwelveHour'); + static const TimeFormat TwentyFourHour = TimeFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TwentyFourHour'); + + static const $core.List values = [ + TwelveHour, + TwentyFourHour, + ]; + + static final $core.Map<$core.int, TimeFormat> _byValue = $pb.ProtobufEnum.initByValue(values); + static TimeFormat? valueOf($core.int value) => _byValue[value]; + + const TimeFormat._($core.int v, $core.String n) : super(v, n); +} + +class MoneySymbol extends $pb.ProtobufEnum { + static const MoneySymbol CNY = MoneySymbol._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CNY'); + static const MoneySymbol EUR = MoneySymbol._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EUR'); + static const MoneySymbol USD = MoneySymbol._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'USD'); + + static const $core.List values = [ + CNY, + EUR, + USD, + ]; + + static final $core.Map<$core.int, MoneySymbol> _byValue = $pb.ProtobufEnum.initByValue(values); + static MoneySymbol? valueOf($core.int value) => _byValue[value]; + + const MoneySymbol._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbjson.dart new file mode 100644 index 0000000000..71e0cf884b --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbjson.dart @@ -0,0 +1,125 @@ +/// +// Generated code. Do not modify. +// source: type_options.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use dateFormatDescriptor instead') +const DateFormat$json = const { + '1': 'DateFormat', + '2': const [ + const {'1': 'Local', '2': 0}, + const {'1': 'US', '2': 1}, + const {'1': 'ISO', '2': 2}, + const {'1': 'Friendly', '2': 3}, + ], +}; + +/// Descriptor for `DateFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List dateFormatDescriptor = $convert.base64Decode('CgpEYXRlRm9ybWF0EgkKBUxvY2FsEAASBgoCVVMQARIHCgNJU08QAhIMCghGcmllbmRseRAD'); +@$core.Deprecated('Use timeFormatDescriptor instead') +const TimeFormat$json = const { + '1': 'TimeFormat', + '2': const [ + const {'1': 'TwelveHour', '2': 0}, + const {'1': 'TwentyFourHour', '2': 1}, + ], +}; + +/// Descriptor for `TimeFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List timeFormatDescriptor = $convert.base64Decode('CgpUaW1lRm9ybWF0Eg4KClR3ZWx2ZUhvdXIQABISCg5Ud2VudHlGb3VySG91chAB'); +@$core.Deprecated('Use moneySymbolDescriptor instead') +const MoneySymbol$json = const { + '1': 'MoneySymbol', + '2': const [ + const {'1': 'CNY', '2': 0}, + const {'1': 'EUR', '2': 1}, + const {'1': 'USD', '2': 2}, + ], +}; + +/// Descriptor for `MoneySymbol`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List moneySymbolDescriptor = $convert.base64Decode('CgtNb25leVN5bWJvbBIHCgNDTlkQABIHCgNFVVIQARIHCgNVU0QQAg=='); +@$core.Deprecated('Use richTextDescriptionDescriptor instead') +const RichTextDescription$json = const { + '1': 'RichTextDescription', + '2': const [ + const {'1': 'format', '3': 1, '4': 1, '5': 9, '10': 'format'}, + ], +}; + +/// Descriptor for `RichTextDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List richTextDescriptionDescriptor = $convert.base64Decode('ChNSaWNoVGV4dERlc2NyaXB0aW9uEhYKBmZvcm1hdBgBIAEoCVIGZm9ybWF0'); +@$core.Deprecated('Use checkboxDescriptionDescriptor instead') +const CheckboxDescription$json = const { + '1': 'CheckboxDescription', + '2': const [ + const {'1': 'is_selected', '3': 1, '4': 1, '5': 8, '10': 'isSelected'}, + ], +}; + +/// Descriptor for `CheckboxDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List checkboxDescriptionDescriptor = $convert.base64Decode('ChNDaGVja2JveERlc2NyaXB0aW9uEh8KC2lzX3NlbGVjdGVkGAEgASgIUgppc1NlbGVjdGVk'); +@$core.Deprecated('Use dateDescriptionDescriptor instead') +const DateDescription$json = const { + '1': 'DateDescription', + '2': const [ + const {'1': 'date_format', '3': 1, '4': 1, '5': 14, '6': '.DateFormat', '10': 'dateFormat'}, + const {'1': 'time_format', '3': 2, '4': 1, '5': 14, '6': '.TimeFormat', '10': 'timeFormat'}, + ], +}; + +/// Descriptor for `DateDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List dateDescriptionDescriptor = $convert.base64Decode('Cg9EYXRlRGVzY3JpcHRpb24SLAoLZGF0ZV9mb3JtYXQYASABKA4yCy5EYXRlRm9ybWF0UgpkYXRlRm9ybWF0EiwKC3RpbWVfZm9ybWF0GAIgASgOMgsuVGltZUZvcm1hdFIKdGltZUZvcm1hdA=='); +@$core.Deprecated('Use singleSelectDescriptionDescriptor instead') +const SingleSelectDescription$json = const { + '1': 'SingleSelectDescription', + '2': const [ + const {'1': 'options', '3': 1, '4': 3, '5': 11, '6': '.SelectOption', '10': 'options'}, + const {'1': 'disable_color', '3': 2, '4': 1, '5': 8, '10': 'disableColor'}, + ], +}; + +/// Descriptor for `SingleSelectDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List singleSelectDescriptionDescriptor = $convert.base64Decode('ChdTaW5nbGVTZWxlY3REZXNjcmlwdGlvbhInCgdvcHRpb25zGAEgAygLMg0uU2VsZWN0T3B0aW9uUgdvcHRpb25zEiMKDWRpc2FibGVfY29sb3IYAiABKAhSDGRpc2FibGVDb2xvcg=='); +@$core.Deprecated('Use multiSelectDescriptionDescriptor instead') +const MultiSelectDescription$json = const { + '1': 'MultiSelectDescription', + '2': const [ + const {'1': 'options', '3': 1, '4': 3, '5': 11, '6': '.SelectOption', '10': 'options'}, + const {'1': 'disable_color', '3': 2, '4': 1, '5': 8, '10': 'disableColor'}, + ], +}; + +/// Descriptor for `MultiSelectDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List multiSelectDescriptionDescriptor = $convert.base64Decode('ChZNdWx0aVNlbGVjdERlc2NyaXB0aW9uEicKB29wdGlvbnMYASADKAsyDS5TZWxlY3RPcHRpb25SB29wdGlvbnMSIwoNZGlzYWJsZV9jb2xvchgCIAEoCFIMZGlzYWJsZUNvbG9y'); +@$core.Deprecated('Use selectOptionDescriptor instead') +const SelectOption$json = const { + '1': 'SelectOption', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, + const {'1': 'color', '3': 3, '4': 1, '5': 9, '10': 'color'}, + ], +}; + +/// Descriptor for `SelectOption`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List selectOptionDescriptor = $convert.base64Decode('CgxTZWxlY3RPcHRpb24SDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSFAoFY29sb3IYAyABKAlSBWNvbG9y'); +@$core.Deprecated('Use numberDescriptionDescriptor instead') +const NumberDescription$json = const { + '1': 'NumberDescription', + '2': const [ + const {'1': 'money', '3': 1, '4': 1, '5': 14, '6': '.MoneySymbol', '10': 'money'}, + const {'1': 'scale', '3': 2, '4': 1, '5': 13, '10': 'scale'}, + const {'1': 'symbol', '3': 3, '4': 1, '5': 9, '10': 'symbol'}, + const {'1': 'sign_positive', '3': 4, '4': 1, '5': 8, '10': 'signPositive'}, + const {'1': 'name', '3': 5, '4': 1, '5': 9, '10': 'name'}, + ], +}; + +/// Descriptor for `NumberDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List numberDescriptionDescriptor = $convert.base64Decode('ChFOdW1iZXJEZXNjcmlwdGlvbhIiCgVtb25leRgBIAEoDjIMLk1vbmV5U3ltYm9sUgVtb25leRIUCgVzY2FsZRgCIAEoDVIFc2NhbGUSFgoGc3ltYm9sGAMgASgJUgZzeW1ib2wSIwoNc2lnbl9wb3NpdGl2ZRgEIAEoCFIMc2lnblBvc2l0aXZlEhIKBG5hbWUYBSABKAlSBG5hbWU='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbserver.dart new file mode 100644 index 0000000000..b46de00bf5 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/type_options.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: type_options.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'type_options.pb.dart'; + diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 6b22e06e0a..5ae075afa3 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1059,8 +1059,10 @@ dependencies = [ "flowy-database", "flowy-derive", "flowy-error", + "flowy-grid", "flowy-grid-data-model", "flowy-sync", + "flowy-test", "lazy_static", "lib-dispatch", "lib-infra", diff --git a/frontend/rust-lib/flowy-block/src/editor.rs b/frontend/rust-lib/flowy-block/src/editor.rs index b5e9e81810..8622c60730 100644 --- a/frontend/rust-lib/flowy-block/src/editor.rs +++ b/frontend/rust-lib/flowy-block/src/editor.rs @@ -39,7 +39,7 @@ impl ClientTextBlockEditor { rev_web_socket: Arc, cloud_service: Arc, ) -> FlowyResult> { - let document_info = rev_manager.load::(cloud_service).await?; + let document_info = rev_manager.load::(Some(cloud_service)).await?; let delta = document_info.delta()?; let rev_manager = Arc::new(rev_manager); let doc_id = doc_id.to_string(); @@ -191,17 +191,9 @@ fn spawn_edit_queue( #[cfg(feature = "flowy_unit_test")] impl ClientTextBlockEditor { - pub async fn doc_json(&self) -> FlowyResult { - let (ret, rx) = oneshot::channel::>(); - let msg = EditorCommand::ReadDeltaStr { ret }; - let _ = self.edit_cmd_tx.send(msg).await; - let s = rx.await.map_err(internal_error)??; - Ok(s) - } - - pub async fn doc_delta(&self) -> FlowyResult { + pub async fn text_block_delta(&self) -> FlowyResult { let (ret, rx) = oneshot::channel::>(); - let msg = EditorCommand::ReadBlockDelta { ret }; + let msg = EditorCommand::ReadDelta { ret }; let _ = self.edit_cmd_tx.send(msg).await; let delta = rx.await.map_err(internal_error)??; Ok(delta) diff --git a/frontend/rust-lib/flowy-block/src/queue.rs b/frontend/rust-lib/flowy-block/src/queue.rs index 087ed9d189..94955f38d8 100644 --- a/frontend/rust-lib/flowy-block/src/queue.rs +++ b/frontend/rust-lib/flowy-block/src/queue.rs @@ -166,7 +166,7 @@ impl EditBlockQueue { let data = self.document.read().await.delta_str(); let _ = ret.send(Ok(data)); } - EditorCommand::ReadBlockDelta { ret } => { + EditorCommand::ReadDelta { ret } => { let delta = self.document.read().await.delta().clone(); let _ = ret.send(Ok(delta)); } @@ -256,7 +256,7 @@ pub(crate) enum EditorCommand { ret: Ret, }, #[allow(dead_code)] - ReadBlockDelta { + ReadDelta { ret: Ret, }, } @@ -277,7 +277,7 @@ impl std::fmt::Debug for EditorCommand { EditorCommand::Undo { .. } => "Undo", EditorCommand::Redo { .. } => "Redo", EditorCommand::ReadDeltaStr { .. } => "ReadDeltaStr", - EditorCommand::ReadBlockDelta { .. } => "ReadDocumentAsDelta", + EditorCommand::ReadDelta { .. } => "ReadDocumentAsDelta", }; f.write_str(s) } diff --git a/frontend/rust-lib/flowy-block/tests/document/mod.rs b/frontend/rust-lib/flowy-block/tests/document/mod.rs index 252787043a..8aa4c774ed 100644 --- a/frontend/rust-lib/flowy-block/tests/document/mod.rs +++ b/frontend/rust-lib/flowy-block/tests/document/mod.rs @@ -1,2 +1,2 @@ -mod document_test; -mod edit_script; +mod script; +mod text_block_test; diff --git a/frontend/rust-lib/flowy-block/tests/document/edit_script.rs b/frontend/rust-lib/flowy-block/tests/document/script.rs similarity index 91% rename from frontend/rust-lib/flowy-block/tests/document/edit_script.rs rename to frontend/rust-lib/flowy-block/tests/document/script.rs index c30ccd8d46..87f52a3e46 100644 --- a/frontend/rust-lib/flowy-block/tests/document/edit_script.rs +++ b/frontend/rust-lib/flowy-block/tests/document/script.rs @@ -17,16 +17,16 @@ pub enum EditorScript { AssertJson(&'static str), } -pub struct EditorTest { +pub struct TextBlockEditorTest { pub sdk: FlowySDKTest, pub editor: Arc, } -impl EditorTest { +impl TextBlockEditorTest { pub async fn new() -> Self { let sdk = FlowySDKTest::default(); let _ = sdk.init_user().await; - let test = ViewTest::new(&sdk).await; + let test = ViewTest::new_grid_view(&sdk).await; let editor = sdk.text_block_manager.open_block(&test.view.id).await.unwrap(); Self { sdk, editor } } @@ -41,8 +41,6 @@ impl EditorTest { let rev_manager = self.editor.rev_manager(); let cache = rev_manager.revision_cache().await; let _user_id = self.sdk.user_session.user_id().unwrap(); - // let ws_manager = self.sdk.ws_conn.clone(); - // let token = self.sdk.user_session.token().unwrap(); match script { EditorScript::InsertText(s, offset) => { @@ -74,7 +72,7 @@ impl EditorTest { } EditorScript::AssertJson(expected) => { let expected_delta: RichTextDelta = serde_json::from_str(expected).unwrap(); - let delta = self.editor.doc_delta().await.unwrap(); + let delta = self.editor.text_block_delta().await.unwrap(); if expected_delta != delta { eprintln!("✅ expect: {}", expected,); eprintln!("❌ receive: {}", delta.to_delta_str()); diff --git a/frontend/rust-lib/flowy-block/tests/document/document_test.rs b/frontend/rust-lib/flowy-block/tests/document/text_block_test.rs similarity index 69% rename from frontend/rust-lib/flowy-block/tests/document/document_test.rs rename to frontend/rust-lib/flowy-block/tests/document/text_block_test.rs index df2282d01f..93fb957cdb 100644 --- a/frontend/rust-lib/flowy-block/tests/document/document_test.rs +++ b/frontend/rust-lib/flowy-block/tests/document/text_block_test.rs @@ -1,9 +1,9 @@ -use crate::document::edit_script::{EditorScript::*, *}; +use crate::document::script::{EditorScript::*, *}; use flowy_sync::disk::RevisionState; use lib_ot::core::{count_utf16_code_units, Interval}; #[tokio::test] -async fn document_sync_current_rev_id_check() { +async fn text_block_sync_current_rev_id_check() { let scripts = vec![ InsertText("1", 0), AssertCurrentRevId(1), @@ -14,11 +14,11 @@ async fn document_sync_current_rev_id_check() { AssertNextSyncRevId(None), AssertJson(r#"[{"insert":"123\n"}]"#), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } #[tokio::test] -async fn document_sync_state_check() { +async fn text_block_sync_state_check() { let scripts = vec![ InsertText("1", 0), InsertText("2", 1), @@ -28,11 +28,11 @@ async fn document_sync_state_check() { AssertRevisionState(3, RevisionState::Ack), AssertJson(r#"[{"insert":"123\n"}]"#), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } #[tokio::test] -async fn document_sync_insert_test() { +async fn text_block_sync_insert_test() { let scripts = vec![ InsertText("1", 0), InsertText("2", 1), @@ -40,11 +40,11 @@ async fn document_sync_insert_test() { AssertJson(r#"[{"insert":"123\n"}]"#), AssertNextSyncRevId(None), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } #[tokio::test] -async fn document_sync_insert_in_chinese() { +async fn text_block_sync_insert_in_chinese() { let s = "好".to_owned(); let offset = count_utf16_code_units(&s); let scripts = vec![ @@ -52,11 +52,11 @@ async fn document_sync_insert_in_chinese() { InsertText("好", offset), AssertJson(r#"[{"insert":"你好\n"}]"#), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } #[tokio::test] -async fn document_sync_insert_with_emoji() { +async fn text_block_sync_insert_with_emoji() { let s = "😁".to_owned(); let offset = count_utf16_code_units(&s); let scripts = vec![ @@ -64,11 +64,11 @@ async fn document_sync_insert_with_emoji() { InsertText("☺️", offset), AssertJson(r#"[{"insert":"😁☺️\n"}]"#), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } #[tokio::test] -async fn document_sync_delete_in_english() { +async fn text_block_sync_delete_in_english() { let scripts = vec![ InsertText("1", 0), InsertText("2", 1), @@ -76,11 +76,11 @@ async fn document_sync_delete_in_english() { Delete(Interval::new(0, 2)), AssertJson(r#"[{"insert":"3\n"}]"#), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } #[tokio::test] -async fn document_sync_delete_in_chinese() { +async fn text_block_sync_delete_in_chinese() { let s = "好".to_owned(); let offset = count_utf16_code_units(&s); let scripts = vec![ @@ -89,11 +89,11 @@ async fn document_sync_delete_in_chinese() { Delete(Interval::new(0, offset)), AssertJson(r#"[{"insert":"好\n"}]"#), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } #[tokio::test] -async fn document_sync_replace_test() { +async fn text_block_sync_replace_test() { let scripts = vec![ InsertText("1", 0), InsertText("2", 1), @@ -101,5 +101,5 @@ async fn document_sync_replace_test() { Replace(Interval::new(0, 3), "abc"), AssertJson(r#"[{"insert":"abc\n"}]"#), ]; - EditorTest::new().await.run_scripts(scripts).await; + TextBlockEditorTest::new().await.run_scripts(scripts).await; } 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 0a5dd7f794..7aaa1de7cd 100644 --- a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs +++ b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs @@ -38,7 +38,7 @@ impl ClientFolderEditor { let cloud = Arc::new(FolderRevisionCloudService { token: token.to_string(), }); - let folder = Arc::new(RwLock::new(rev_manager.load::(cloud).await?)); + let folder = Arc::new(RwLock::new(rev_manager.load::(Some(cloud)).await?)); let rev_manager = Arc::new(rev_manager); let ws_manager = make_folder_ws_manager( user_id, diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs b/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs index 7dd5b66e2f..9f9bae4a82 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs @@ -1,6 +1,7 @@ use crate::script::{invalid_workspace_name_test_case, FolderScript::*, FolderTest}; use flowy_folder::entities::workspace::CreateWorkspacePayload; +use flowy_folder_data_model::entities::view::ViewDataType; use flowy_sync::disk::RevisionState; use flowy_test::{event_builder::*, FlowySDKTest}; @@ -136,10 +137,12 @@ async fn app_create_with_view() { CreateView { name: "View A".to_owned(), desc: "View A description".to_owned(), + data_type: ViewDataType::TextBlock, }, CreateView { - name: "View B".to_owned(), - desc: "View B description".to_owned(), + name: "Grid".to_owned(), + desc: "Grid description".to_owned(), + data_type: ViewDataType::Grid, }, ReadApp(app.id), ]) @@ -148,7 +151,7 @@ async fn app_create_with_view() { app = test.app.clone(); assert_eq!(app.belongings.len(), 3); assert_eq!(app.belongings[1].name, "View A"); - assert_eq!(app.belongings[2].name, "View B") + assert_eq!(app.belongings[2].name, "Grid") } #[tokio::test] @@ -198,10 +201,12 @@ async fn view_delete_all() { CreateView { name: "View A".to_owned(), desc: "View A description".to_owned(), + data_type: ViewDataType::TextBlock, }, CreateView { - name: "View B".to_owned(), - desc: "View B description".to_owned(), + name: "Grid".to_owned(), + desc: "Grid description".to_owned(), + data_type: ViewDataType::Grid, }, ReadApp(app.id.clone()), ]) @@ -229,6 +234,7 @@ async fn view_delete_all_permanent() { CreateView { name: "View A".to_owned(), desc: "View A description".to_owned(), + data_type: ViewDataType::TextBlock, }, ReadApp(app.id.clone()), ]) @@ -327,6 +333,7 @@ async fn folder_sync_revision_with_new_view() { CreateView { name: view_name.clone(), desc: view_desc.clone(), + data_type: ViewDataType::TextBlock, }, AssertCurrentRevId(3), AssertNextSyncRevId(Some(3)), diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs b/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs deleted file mode 100644 index 93e2ff2b7f..0000000000 --- a/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs +++ /dev/null @@ -1,212 +0,0 @@ -use flowy_collaboration::entities::text_block_info::TextBlockInfo; -use flowy_folder::event_map::FolderEvent::*; -use flowy_folder_data_model::entities::view::{RepeatedViewId, ViewId}; -use flowy_folder_data_model::entities::workspace::WorkspaceId; -use flowy_folder_data_model::entities::{ - app::{App, AppId, CreateAppPayload, UpdateAppPayload}, - trash::{RepeatedTrash, TrashId, TrashType}, - view::{CreateViewPayload, UpdateViewPayload, View, ViewDataType}, - workspace::{CreateWorkspacePayload, RepeatedWorkspace, Workspace}, -}; -use flowy_test::{event_builder::*, FlowySDKTest}; - -pub async fn create_workspace(sdk: &FlowySDKTest, name: &str, desc: &str) -> Workspace { - let request = CreateWorkspacePayload { - name: name.to_owned(), - desc: desc.to_owned(), - }; - - let workspace = FolderEventBuilder::new(sdk.clone()) - .event(CreateWorkspace) - .payload(request) - .async_send() - .await - .parse::(); - workspace -} - -pub async fn read_workspace(sdk: &FlowySDKTest, workspace_id: Option) -> Vec { - let request = WorkspaceId { value: workspace_id }; - let repeated_workspace = FolderEventBuilder::new(sdk.clone()) - .event(ReadWorkspaces) - .payload(request.clone()) - .async_send() - .await - .parse::(); - - let workspaces; - if let Some(workspace_id) = &request.value { - workspaces = repeated_workspace - .into_inner() - .into_iter() - .filter(|workspace| &workspace.id == workspace_id) - .collect::>(); - debug_assert_eq!(workspaces.len(), 1); - } else { - workspaces = repeated_workspace.items; - } - - workspaces -} - -pub async fn create_app(sdk: &FlowySDKTest, workspace_id: &str, name: &str, desc: &str) -> App { - let create_app_request = CreateAppPayload { - workspace_id: workspace_id.to_owned(), - name: name.to_string(), - desc: desc.to_string(), - color_style: Default::default(), - }; - - let app = FolderEventBuilder::new(sdk.clone()) - .event(CreateApp) - .payload(create_app_request) - .async_send() - .await - .parse::(); - app -} - -pub async fn read_app(sdk: &FlowySDKTest, app_id: &str) -> App { - let request = AppId { - value: app_id.to_owned(), - }; - - let app = FolderEventBuilder::new(sdk.clone()) - .event(ReadApp) - .payload(request) - .async_send() - .await - .parse::(); - - app -} - -pub async fn update_app(sdk: &FlowySDKTest, app_id: &str, name: Option, desc: Option) { - let request = UpdateAppPayload { - app_id: app_id.to_string(), - name, - desc, - color_style: None, - is_trash: None, - }; - - FolderEventBuilder::new(sdk.clone()) - .event(UpdateApp) - .payload(request) - .async_send() - .await; -} - -pub async fn delete_app(sdk: &FlowySDKTest, app_id: &str) { - let request = AppId { - value: app_id.to_string(), - }; - - FolderEventBuilder::new(sdk.clone()) - .event(DeleteApp) - .payload(request) - .async_send() - .await; -} - -pub async fn create_view(sdk: &FlowySDKTest, app_id: &str, name: &str, desc: &str, data_type: ViewDataType) -> View { - let request = CreateViewPayload { - belong_to_id: app_id.to_string(), - name: name.to_string(), - desc: desc.to_string(), - thumbnail: None, - data_type, - ext_data: "".to_string(), - plugin_type: 0, - }; - let view = FolderEventBuilder::new(sdk.clone()) - .event(CreateView) - .payload(request) - .async_send() - .await - .parse::(); - view -} - -pub async fn read_view(sdk: &FlowySDKTest, view_id: &str) -> View { - let view_id: ViewId = view_id.into(); - FolderEventBuilder::new(sdk.clone()) - .event(ReadView) - .payload(view_id) - .async_send() - .await - .parse::() -} - -pub async fn update_view(sdk: &FlowySDKTest, view_id: &str, name: Option, desc: Option) { - let request = UpdateViewPayload { - view_id: view_id.to_string(), - name, - desc, - thumbnail: None, - }; - FolderEventBuilder::new(sdk.clone()) - .event(UpdateView) - .payload(request) - .async_send() - .await; -} - -pub async fn delete_view(sdk: &FlowySDKTest, view_ids: Vec) { - let request = RepeatedViewId { items: view_ids }; - FolderEventBuilder::new(sdk.clone()) - .event(DeleteView) - .payload(request) - .async_send() - .await; -} - -#[allow(dead_code)] -pub async fn set_latest_view(sdk: &FlowySDKTest, view_id: &str) -> TextBlockInfo { - let view_id: ViewId = view_id.into(); - FolderEventBuilder::new(sdk.clone()) - .event(SetLatestView) - .payload(view_id) - .async_send() - .await - .parse::() -} - -pub async fn read_trash(sdk: &FlowySDKTest) -> RepeatedTrash { - FolderEventBuilder::new(sdk.clone()) - .event(ReadTrash) - .async_send() - .await - .parse::() -} - -pub async fn restore_app_from_trash(sdk: &FlowySDKTest, app_id: &str) { - let id = TrashId { - id: app_id.to_owned(), - ty: TrashType::TrashApp, - }; - FolderEventBuilder::new(sdk.clone()) - .event(PutbackTrash) - .payload(id) - .async_send() - .await; -} - -pub async fn restore_view_from_trash(sdk: &FlowySDKTest, view_id: &str) { - let id = TrashId { - id: view_id.to_owned(), - ty: TrashType::TrashView, - }; - FolderEventBuilder::new(sdk.clone()) - .event(PutbackTrash) - .payload(id) - .async_send() - .await; -} - -pub async fn delete_all_trash(sdk: &FlowySDKTest) { - FolderEventBuilder::new(sdk.clone()) - .event(DeleteAllTrash) - .async_send() - .await; -} diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/main.rs b/frontend/rust-lib/flowy-folder/tests/workspace/main.rs index 553449ee4b..ff48b349e1 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/main.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/main.rs @@ -1,3 +1,2 @@ mod folder_test; -mod helper; mod script; diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index 7674ca0a54..9c2c8ecbed 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs @@ -1,39 +1,63 @@ -use crate::helper::*; - +use flowy_collaboration::entities::text_block_info::TextBlockInfo; +use flowy_folder::event_map::FolderEvent::*; use flowy_folder::{errors::ErrorCode, services::folder_editor::ClientFolderEditor}; +use flowy_folder_data_model::entities::view::{RepeatedViewId, ViewId}; +use flowy_folder_data_model::entities::workspace::WorkspaceId; use flowy_folder_data_model::entities::{ app::{App, RepeatedApp}, trash::Trash, view::{RepeatedView, View, ViewDataType}, workspace::Workspace, }; +use flowy_folder_data_model::entities::{ + app::{AppId, CreateAppPayload, UpdateAppPayload}, + trash::{RepeatedTrash, TrashId, TrashType}, + view::{CreateViewPayload, UpdateViewPayload}, + workspace::{CreateWorkspacePayload, RepeatedWorkspace}, +}; use flowy_sync::disk::RevisionState; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; -use flowy_test::FlowySDKTest; +use flowy_test::{event_builder::*, FlowySDKTest}; use std::{sync::Arc, time::Duration}; use tokio::time::sleep; pub enum FolderScript { // Workspace ReadAllWorkspaces, - CreateWorkspace { name: String, desc: String }, + CreateWorkspace { + name: String, + desc: String, + }, AssertWorkspaceJson(String), AssertWorkspace(Workspace), ReadWorkspace(Option), // App - CreateApp { name: String, desc: String }, + CreateApp { + name: String, + desc: String, + }, AssertAppJson(String), AssertApp(App), ReadApp(String), - UpdateApp { name: Option, desc: Option }, + UpdateApp { + name: Option, + desc: Option, + }, DeleteApp, // View - CreateView { name: String, desc: String }, + CreateView { + name: String, + desc: String, + data_type: ViewDataType, + }, AssertView(View), ReadView(String), - UpdateView { name: Option, desc: Option }, + UpdateView { + name: Option, + desc: Option, + }, DeleteView, DeleteViews(Vec), @@ -46,7 +70,10 @@ pub enum FolderScript { // Sync AssertCurrentRevId(i64), AssertNextSyncRevId(Option), - AssertRevisionState { rev_id: i64, state: RevisionState }, + AssertRevisionState { + rev_id: i64, + state: RevisionState, + }, } pub struct FolderTest { @@ -148,8 +175,8 @@ impl FolderTest { delete_app(sdk, &self.app.id).await; } - FolderScript::CreateView { name, desc } => { - let view = create_view(sdk, &self.app.id, &name, &desc, ViewDataType::TextBlock).await; + FolderScript::CreateView { name, desc, data_type } => { + let view = create_view(sdk, &self.app.id, &name, &desc, data_type).await; self.view = view; } FolderScript::AssertView(view) => { @@ -216,3 +243,204 @@ pub fn invalid_workspace_name_test_case() -> Vec<(String, ErrorCode)> { ("1234".repeat(100), ErrorCode::WorkspaceNameTooLong), ] } + +pub async fn create_workspace(sdk: &FlowySDKTest, name: &str, desc: &str) -> Workspace { + let request = CreateWorkspacePayload { + name: name.to_owned(), + desc: desc.to_owned(), + }; + + let workspace = FolderEventBuilder::new(sdk.clone()) + .event(CreateWorkspace) + .payload(request) + .async_send() + .await + .parse::(); + workspace +} + +pub async fn read_workspace(sdk: &FlowySDKTest, workspace_id: Option) -> Vec { + let request = WorkspaceId { value: workspace_id }; + let repeated_workspace = FolderEventBuilder::new(sdk.clone()) + .event(ReadWorkspaces) + .payload(request.clone()) + .async_send() + .await + .parse::(); + + let workspaces; + if let Some(workspace_id) = &request.value { + workspaces = repeated_workspace + .into_inner() + .into_iter() + .filter(|workspace| &workspace.id == workspace_id) + .collect::>(); + debug_assert_eq!(workspaces.len(), 1); + } else { + workspaces = repeated_workspace.items; + } + + workspaces +} + +pub async fn create_app(sdk: &FlowySDKTest, workspace_id: &str, name: &str, desc: &str) -> App { + let create_app_request = CreateAppPayload { + workspace_id: workspace_id.to_owned(), + name: name.to_string(), + desc: desc.to_string(), + color_style: Default::default(), + }; + + let app = FolderEventBuilder::new(sdk.clone()) + .event(CreateApp) + .payload(create_app_request) + .async_send() + .await + .parse::(); + app +} + +pub async fn read_app(sdk: &FlowySDKTest, app_id: &str) -> App { + let request = AppId { + value: app_id.to_owned(), + }; + + let app = FolderEventBuilder::new(sdk.clone()) + .event(ReadApp) + .payload(request) + .async_send() + .await + .parse::(); + + app +} + +pub async fn update_app(sdk: &FlowySDKTest, app_id: &str, name: Option, desc: Option) { + let request = UpdateAppPayload { + app_id: app_id.to_string(), + name, + desc, + color_style: None, + is_trash: None, + }; + + FolderEventBuilder::new(sdk.clone()) + .event(UpdateApp) + .payload(request) + .async_send() + .await; +} + +pub async fn delete_app(sdk: &FlowySDKTest, app_id: &str) { + let request = AppId { + value: app_id.to_string(), + }; + + FolderEventBuilder::new(sdk.clone()) + .event(DeleteApp) + .payload(request) + .async_send() + .await; +} + +pub async fn create_view(sdk: &FlowySDKTest, app_id: &str, name: &str, desc: &str, data_type: ViewDataType) -> View { + let request = CreateViewPayload { + belong_to_id: app_id.to_string(), + name: name.to_string(), + desc: desc.to_string(), + thumbnail: None, + data_type, + ext_data: "".to_string(), + plugin_type: 0, + }; + let view = FolderEventBuilder::new(sdk.clone()) + .event(CreateView) + .payload(request) + .async_send() + .await + .parse::(); + view +} + +pub async fn read_view(sdk: &FlowySDKTest, view_id: &str) -> View { + let view_id: ViewId = view_id.into(); + FolderEventBuilder::new(sdk.clone()) + .event(ReadView) + .payload(view_id) + .async_send() + .await + .parse::() +} + +pub async fn update_view(sdk: &FlowySDKTest, view_id: &str, name: Option, desc: Option) { + let request = UpdateViewPayload { + view_id: view_id.to_string(), + name, + desc, + thumbnail: None, + }; + FolderEventBuilder::new(sdk.clone()) + .event(UpdateView) + .payload(request) + .async_send() + .await; +} + +pub async fn delete_view(sdk: &FlowySDKTest, view_ids: Vec) { + let request = RepeatedViewId { items: view_ids }; + FolderEventBuilder::new(sdk.clone()) + .event(DeleteView) + .payload(request) + .async_send() + .await; +} + +#[allow(dead_code)] +pub async fn set_latest_view(sdk: &FlowySDKTest, view_id: &str) -> TextBlockInfo { + let view_id: ViewId = view_id.into(); + FolderEventBuilder::new(sdk.clone()) + .event(SetLatestView) + .payload(view_id) + .async_send() + .await + .parse::() +} + +pub async fn read_trash(sdk: &FlowySDKTest) -> RepeatedTrash { + FolderEventBuilder::new(sdk.clone()) + .event(ReadTrash) + .async_send() + .await + .parse::() +} + +pub async fn restore_app_from_trash(sdk: &FlowySDKTest, app_id: &str) { + let id = TrashId { + id: app_id.to_owned(), + ty: TrashType::TrashApp, + }; + FolderEventBuilder::new(sdk.clone()) + .event(PutbackTrash) + .payload(id) + .async_send() + .await; +} + +pub async fn restore_view_from_trash(sdk: &FlowySDKTest, view_id: &str) { + let id = TrashId { + id: view_id.to_owned(), + ty: TrashType::TrashView, + }; + FolderEventBuilder::new(sdk.clone()) + .event(PutbackTrash) + .payload(id) + .async_send() + .await; +} + +pub async fn delete_all_trash(sdk: &FlowySDKTest) { + FolderEventBuilder::new(sdk.clone()) + .event(DeleteAllTrash) + .async_send() + .await; +} diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index 95a5899f5e..48c7e346a4 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -34,10 +34,15 @@ tokio = {version = "1", features = ["sync"]} rayon = "1.5" parking_lot = "0.11" +[dev-dependencies] +flowy-test = { path = "../flowy-test" } +flowy-grid = { path = "../flowy-grid", features = ["flowy_unit_test"]} + [build-dependencies] lib-infra = { path = "../../../shared-lib/lib-infra", features = ["protobuf_file_gen", "proto_gen"] } [features] default = [] -dart = ["lib-infra/dart"] \ No newline at end of file +dart = ["lib-infra/dart"] +flowy_unit_test = ["flowy-sync/flowy_unit_test"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/Flowy.toml b/frontend/rust-lib/flowy-grid/Flowy.toml index d7c3d8260d..fc5c01c773 100644 --- a/frontend/rust-lib/flowy-grid/Flowy.toml +++ b/frontend/rust-lib/flowy-grid/Flowy.toml @@ -1,3 +1,3 @@ -proto_crates = ["src/event_map.rs", "src/services/cell_data.rs"] +proto_crates = ["src/event_map.rs", "src/services/field/type_options.rs"] event_files = ["src/event_map.rs"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/src/lib.rs b/frontend/rust-lib/flowy-grid/src/lib.rs index 262fe1d1c2..526e1e4267 100644 --- a/frontend/rust-lib/flowy-grid/src/lib.rs +++ b/frontend/rust-lib/flowy-grid/src/lib.rs @@ -7,3 +7,4 @@ pub mod manager; mod protobuf; pub mod services; +pub mod util; diff --git a/frontend/rust-lib/flowy-grid/src/macros.rs b/frontend/rust-lib/flowy-grid/src/macros.rs index 043dcccb44..9f2fedddc7 100644 --- a/frontend/rust-lib/flowy-grid/src/macros.rs +++ b/frontend/rust-lib/flowy-grid/src/macros.rs @@ -1,29 +1,17 @@ #[macro_export] -macro_rules! impl_any_data { +macro_rules! impl_from_and_to_type_option { ($target: ident, $field_type:expr) => { - impl_field_type_data_from_field!($target); - impl_field_type_data_from_field_type_option!($target); - impl_type_option_from_field_data!($target, $field_type); + impl_from_field_type_option!($target); + impl_to_field_type_option!($target, $field_type); }; } #[macro_export] -macro_rules! impl_field_type_data_from_field { +macro_rules! impl_from_field_type_option { ($target: ident) => { impl std::convert::From<&Field> for $target { fn from(field: &Field) -> $target { - $target::from(&field.type_options) - } - } - }; -} - -#[macro_export] -macro_rules! impl_field_type_data_from_field_type_option { - ($target: ident) => { - impl std::convert::From<&AnyData> for $target { - fn from(any_data: &AnyData) -> $target { - match $target::try_from(Bytes::from(any_data.value.clone())) { + match $target::try_from(Bytes::from(field.type_options.value.clone())) { Ok(obj) => obj, Err(err) => { tracing::error!("{} convert from any data failed, {:?}", stringify!($target), err); @@ -36,26 +24,27 @@ macro_rules! impl_field_type_data_from_field_type_option { } #[macro_export] -macro_rules! impl_type_option_from_field_data { +macro_rules! impl_to_field_type_option { ($target: ident, $field_type:expr) => { impl $target { - pub fn field_type() -> FieldType { + pub fn field_type(&self) -> FieldType { $field_type } } impl std::convert::From<$target> for AnyData { - fn from(field_data: $target) -> Self { - match field_data.try_into() { + fn from(field_description: $target) -> Self { + let field_type = field_description.field_type(); + match field_description.try_into() { Ok(bytes) => { let bytes: Bytes = bytes; - AnyData::from_bytes(&$target::field_type(), bytes) + AnyData::from_bytes(field_type, bytes) } Err(e) => { tracing::error!("Field type data convert to AnyData fail, error: {:?}", e); // it's impossible to fail when unwrapping the default field type data let default_bytes: Bytes = $target::default().try_into().unwrap(); - AnyData::from_bytes(&$target::field_type(), default_bytes) + AnyData::from_bytes(field_type, default_bytes) } } } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 05e61b26ce..fc79fcf5c0 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -113,7 +113,7 @@ impl GridManager { Ok(grid_editor) } - fn make_grid_rev_manager(&self, grid_id: &str, pool: Arc) -> FlowyResult { + pub fn make_grid_rev_manager(&self, grid_id: &str, pool: Arc) -> FlowyResult { let user_id = self.grid_user.user_id()?; let disk_cache = Arc::new(SQLiteGridRevisionPersistence::new(&user_id, pool)); diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs index 55aeddc863..d9c75efb74 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs @@ -1,8 +1,8 @@ #![cfg_attr(rustfmt, rustfmt::skip)] // Auto-generated, do not edit -mod cell_data; -pub use cell_data::*; +mod type_options; +pub use type_options::*; mod event_map; pub use event_map::*; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_data.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/type_options.rs similarity index 91% rename from frontend/rust-lib/flowy-grid/src/protobuf/model/cell_data.rs rename to frontend/rust-lib/flowy-grid/src/protobuf/model/type_options.rs index d173fe22d0..cda2c556c3 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_data.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/type_options.rs @@ -17,7 +17,7 @@ #![allow(trivial_casts)] #![allow(unused_imports)] #![allow(unused_results)] -//! Generated file from `cell_data.proto` +//! Generated file from `type_options.proto` /// Generated files are compatible only with the same version /// of protobuf runtime. @@ -514,7 +514,7 @@ impl ::protobuf::reflect::ProtobufValue for DateDescription { } #[derive(PartialEq,Clone,Default)] -pub struct SingleSelect { +pub struct SingleSelectDescription { // message fields pub options: ::protobuf::RepeatedField, pub disable_color: bool, @@ -523,14 +523,14 @@ pub struct SingleSelect { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a SingleSelect { - fn default() -> &'a SingleSelect { - ::default_instance() +impl<'a> ::std::default::Default for &'a SingleSelectDescription { + fn default() -> &'a SingleSelectDescription { + ::default_instance() } } -impl SingleSelect { - pub fn new() -> SingleSelect { +impl SingleSelectDescription { + pub fn new() -> SingleSelectDescription { ::std::default::Default::default() } @@ -575,7 +575,7 @@ impl SingleSelect { } } -impl ::protobuf::Message for SingleSelect { +impl ::protobuf::Message for SingleSelectDescription { fn is_initialized(&self) -> bool { for v in &self.options { if !v.is_initialized() { @@ -662,8 +662,8 @@ impl ::protobuf::Message for SingleSelect { Self::descriptor_static() } - fn new() -> SingleSelect { - SingleSelect::new() + fn new() -> SingleSelectDescription { + SingleSelectDescription::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -672,29 +672,29 @@ impl ::protobuf::Message for SingleSelect { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "options", - |m: &SingleSelect| { &m.options }, - |m: &mut SingleSelect| { &mut m.options }, + |m: &SingleSelectDescription| { &m.options }, + |m: &mut SingleSelectDescription| { &mut m.options }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( "disable_color", - |m: &SingleSelect| { &m.disable_color }, - |m: &mut SingleSelect| { &mut m.disable_color }, + |m: &SingleSelectDescription| { &m.disable_color }, + |m: &mut SingleSelectDescription| { &mut m.disable_color }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "SingleSelect", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SingleSelectDescription", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static SingleSelect { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(SingleSelect::new) + fn default_instance() -> &'static SingleSelectDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SingleSelectDescription::new) } } -impl ::protobuf::Clear for SingleSelect { +impl ::protobuf::Clear for SingleSelectDescription { fn clear(&mut self) { self.options.clear(); self.disable_color = false; @@ -702,20 +702,20 @@ impl ::protobuf::Clear for SingleSelect { } } -impl ::std::fmt::Debug for SingleSelect { +impl ::std::fmt::Debug for SingleSelectDescription { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for SingleSelect { +impl ::protobuf::reflect::ProtobufValue for SingleSelectDescription { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } #[derive(PartialEq,Clone,Default)] -pub struct MultiSelect { +pub struct MultiSelectDescription { // message fields pub options: ::protobuf::RepeatedField, pub disable_color: bool, @@ -724,14 +724,14 @@ pub struct MultiSelect { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a MultiSelect { - fn default() -> &'a MultiSelect { - ::default_instance() +impl<'a> ::std::default::Default for &'a MultiSelectDescription { + fn default() -> &'a MultiSelectDescription { + ::default_instance() } } -impl MultiSelect { - pub fn new() -> MultiSelect { +impl MultiSelectDescription { + pub fn new() -> MultiSelectDescription { ::std::default::Default::default() } @@ -776,7 +776,7 @@ impl MultiSelect { } } -impl ::protobuf::Message for MultiSelect { +impl ::protobuf::Message for MultiSelectDescription { fn is_initialized(&self) -> bool { for v in &self.options { if !v.is_initialized() { @@ -863,8 +863,8 @@ impl ::protobuf::Message for MultiSelect { Self::descriptor_static() } - fn new() -> MultiSelect { - MultiSelect::new() + fn new() -> MultiSelectDescription { + MultiSelectDescription::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -873,29 +873,29 @@ impl ::protobuf::Message for MultiSelect { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "options", - |m: &MultiSelect| { &m.options }, - |m: &mut MultiSelect| { &mut m.options }, + |m: &MultiSelectDescription| { &m.options }, + |m: &mut MultiSelectDescription| { &mut m.options }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( "disable_color", - |m: &MultiSelect| { &m.disable_color }, - |m: &mut MultiSelect| { &mut m.disable_color }, + |m: &MultiSelectDescription| { &m.disable_color }, + |m: &mut MultiSelectDescription| { &mut m.disable_color }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "MultiSelect", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MultiSelectDescription", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static MultiSelect { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(MultiSelect::new) + fn default_instance() -> &'static MultiSelectDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MultiSelectDescription::new) } } -impl ::protobuf::Clear for MultiSelect { +impl ::protobuf::Clear for MultiSelectDescription { fn clear(&mut self) { self.options.clear(); self.disable_color = false; @@ -903,13 +903,13 @@ impl ::protobuf::Clear for MultiSelect { } } -impl ::std::fmt::Debug for MultiSelect { +impl ::std::fmt::Debug for MultiSelectDescription { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for MultiSelect { +impl ::protobuf::reflect::ProtobufValue for MultiSelectDescription { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -1161,7 +1161,7 @@ impl ::protobuf::reflect::ProtobufValue for SelectOption { #[derive(PartialEq,Clone,Default)] pub struct NumberDescription { // message fields - pub money: FlowyMoney, + pub money: MoneySymbol, pub scale: u32, pub symbol: ::std::string::String, pub sign_positive: bool, @@ -1182,18 +1182,18 @@ impl NumberDescription { ::std::default::Default::default() } - // .FlowyMoney money = 1; + // .MoneySymbol money = 1; - pub fn get_money(&self) -> FlowyMoney { + pub fn get_money(&self) -> MoneySymbol { self.money } pub fn clear_money(&mut self) { - self.money = FlowyMoney::CNY; + self.money = MoneySymbol::CNY; } // Param is passed by value, moved - pub fn set_money(&mut self, v: FlowyMoney) { + pub fn set_money(&mut self, v: MoneySymbol) { self.money = v; } @@ -1324,7 +1324,7 @@ impl ::protobuf::Message for NumberDescription { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if self.money != FlowyMoney::CNY { + if self.money != MoneySymbol::CNY { my_size += ::protobuf::rt::enum_size(1, self.money); } if self.scale != 0 { @@ -1345,7 +1345,7 @@ impl ::protobuf::Message for NumberDescription { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.money != FlowyMoney::CNY { + if self.money != MoneySymbol::CNY { os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.money))?; } if self.scale != 0 { @@ -1398,7 +1398,7 @@ impl ::protobuf::Message for NumberDescription { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( "money", |m: &NumberDescription| { &m.money }, |m: &mut NumberDescription| { &mut m.money }, @@ -1439,7 +1439,7 @@ impl ::protobuf::Message for NumberDescription { impl ::protobuf::Clear for NumberDescription { fn clear(&mut self) { - self.money = FlowyMoney::CNY; + self.money = MoneySymbol::CNY; self.scale = 0; self.symbol.clear(); self.sign_positive = false; @@ -1567,31 +1567,31 @@ impl ::protobuf::reflect::ProtobufValue for TimeFormat { } #[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum FlowyMoney { +pub enum MoneySymbol { CNY = 0, EUR = 1, USD = 2, } -impl ::protobuf::ProtobufEnum for FlowyMoney { +impl ::protobuf::ProtobufEnum for MoneySymbol { fn value(&self) -> i32 { *self as i32 } - fn from_i32(value: i32) -> ::std::option::Option { + fn from_i32(value: i32) -> ::std::option::Option { match value { - 0 => ::std::option::Option::Some(FlowyMoney::CNY), - 1 => ::std::option::Option::Some(FlowyMoney::EUR), - 2 => ::std::option::Option::Some(FlowyMoney::USD), + 0 => ::std::option::Option::Some(MoneySymbol::CNY), + 1 => ::std::option::Option::Some(MoneySymbol::EUR), + 2 => ::std::option::Option::Some(MoneySymbol::USD), _ => ::std::option::Option::None } } fn values() -> &'static [Self] { - static values: &'static [FlowyMoney] = &[ - FlowyMoney::CNY, - FlowyMoney::EUR, - FlowyMoney::USD, + static values: &'static [MoneySymbol] = &[ + MoneySymbol::CNY, + MoneySymbol::EUR, + MoneySymbol::USD, ]; values } @@ -1599,47 +1599,48 @@ impl ::protobuf::ProtobufEnum for FlowyMoney { fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("FlowyMoney", file_descriptor_proto()) + ::protobuf::reflect::EnumDescriptor::new_pb_name::("MoneySymbol", file_descriptor_proto()) }) } } -impl ::std::marker::Copy for FlowyMoney { +impl ::std::marker::Copy for MoneySymbol { } -impl ::std::default::Default for FlowyMoney { +impl ::std::default::Default for MoneySymbol { fn default() -> Self { - FlowyMoney::CNY + MoneySymbol::CNY } } -impl ::protobuf::reflect::ProtobufValue for FlowyMoney { +impl ::protobuf::reflect::ProtobufValue for MoneySymbol { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) } } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fcell_data.proto\"-\n\x13RichTextDescription\x12\x16\n\x06format\ + \n\x12type_options.proto\"-\n\x13RichTextDescription\x12\x16\n\x06format\ \x18\x01\x20\x01(\tR\x06format\"6\n\x13CheckboxDescription\x12\x1f\n\x0b\ is_selected\x18\x01\x20\x01(\x08R\nisSelected\"m\n\x0fDateDescription\ \x12,\n\x0bdate_format\x18\x01\x20\x01(\x0e2\x0b.DateFormatR\ndateFormat\ \x12,\n\x0btime_format\x18\x02\x20\x01(\x0e2\x0b.TimeFormatR\ntimeFormat\ - \"\\\n\x0cSingleSelect\x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.SelectO\ - ptionR\x07options\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\x0cdisable\ - Color\"[\n\x0bMultiSelect\x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.Sele\ - ctOptionR\x07options\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\x0cdisa\ - bleColor\"H\n\x0cSelectOption\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ - \x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x14\n\x05color\x18\ - \x03\x20\x01(\tR\x05color\"\x9d\x01\n\x11NumberDescription\x12!\n\x05mon\ - ey\x18\x01\x20\x01(\x0e2\x0b.FlowyMoneyR\x05money\x12\x14\n\x05scale\x18\ - \x02\x20\x01(\rR\x05scale\x12\x16\n\x06symbol\x18\x03\x20\x01(\tR\x06sym\ - bol\x12#\n\rsign_positive\x18\x04\x20\x01(\x08R\x0csignPositive\x12\x12\ - \n\x04name\x18\x05\x20\x01(\tR\x04name*6\n\nDateFormat\x12\t\n\x05Local\ - \x10\0\x12\x06\n\x02US\x10\x01\x12\x07\n\x03ISO\x10\x02\x12\x0c\n\x08Fri\ - endly\x10\x03*0\n\nTimeFormat\x12\x0e\n\nTwelveHour\x10\0\x12\x12\n\x0eT\ - wentyFourHour\x10\x01*'\n\nFlowyMoney\x12\x07\n\x03CNY\x10\0\x12\x07\n\ - \x03EUR\x10\x01\x12\x07\n\x03USD\x10\x02b\x06proto3\ + \"g\n\x17SingleSelectDescription\x12'\n\x07options\x18\x01\x20\x03(\x0b2\ + \r.SelectOptionR\x07options\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\ + \x0cdisableColor\"f\n\x16MultiSelectDescription\x12'\n\x07options\x18\ + \x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x12#\n\rdisable_color\x18\ + \x02\x20\x01(\x08R\x0cdisableColor\"H\n\x0cSelectOption\x12\x0e\n\x02id\ + \x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\ + \x12\x14\n\x05color\x18\x03\x20\x01(\tR\x05color\"\x9e\x01\n\x11NumberDe\ + scription\x12\"\n\x05money\x18\x01\x20\x01(\x0e2\x0c.MoneySymbolR\x05mon\ + ey\x12\x14\n\x05scale\x18\x02\x20\x01(\rR\x05scale\x12\x16\n\x06symbol\ + \x18\x03\x20\x01(\tR\x06symbol\x12#\n\rsign_positive\x18\x04\x20\x01(\ + \x08R\x0csignPositive\x12\x12\n\x04name\x18\x05\x20\x01(\tR\x04name*6\n\ + \nDateFormat\x12\t\n\x05Local\x10\0\x12\x06\n\x02US\x10\x01\x12\x07\n\ + \x03ISO\x10\x02\x12\x0c\n\x08Friendly\x10\x03*0\n\nTimeFormat\x12\x0e\n\ + \nTwelveHour\x10\0\x12\x12\n\x0eTwentyFourHour\x10\x01*(\n\x0bMoneySymbo\ + l\x12\x07\n\x03CNY\x10\0\x12\x07\n\x03EUR\x10\x01\x12\x07\n\x03USD\x10\ + \x02b\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/cell_data.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/type_options.proto similarity index 87% rename from frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_data.proto rename to frontend/rust-lib/flowy-grid/src/protobuf/proto/type_options.proto index dc146af19e..170035085c 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_data.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/type_options.proto @@ -10,11 +10,11 @@ message DateDescription { DateFormat date_format = 1; TimeFormat time_format = 2; } -message SingleSelect { +message SingleSelectDescription { repeated SelectOption options = 1; bool disable_color = 2; } -message MultiSelect { +message MultiSelectDescription { repeated SelectOption options = 1; bool disable_color = 2; } @@ -24,7 +24,7 @@ message SelectOption { string color = 3; } message NumberDescription { - FlowyMoney money = 1; + MoneySymbol money = 1; uint32 scale = 2; string symbol = 3; bool sign_positive = 4; @@ -40,7 +40,7 @@ enum TimeFormat { TwelveHour = 0; TwentyFourHour = 1; } -enum FlowyMoney { +enum MoneySymbol { CNY = 0; EUR = 1; USD = 2; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/cell_stringify.rs b/frontend/rust-lib/flowy-grid/src/services/field/cell_stringify.rs new file mode 100644 index 0000000000..a75506e339 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/field/cell_stringify.rs @@ -0,0 +1,34 @@ +use crate::services::field::*; +use crate::services::util::*; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; + +pub trait StringifyCellData { + fn str_from_cell_data(&self, data: AnyData) -> String; + fn str_to_cell_data(&self, s: &str) -> Result; +} + +#[allow(dead_code)] +pub fn stringify_serialize(field: &Field, s: &str) -> Result { + match field.field_type { + FieldType::RichText => RichTextDescription::from(field).str_to_cell_data(s), + FieldType::Number => NumberDescription::from(field).str_to_cell_data(s), + FieldType::DateTime => DateDescription::from(field).str_to_cell_data(s), + FieldType::SingleSelect => SingleSelectDescription::from(field).str_to_cell_data(s), + FieldType::MultiSelect => MultiSelectDescription::from(field).str_to_cell_data(s), + FieldType::Checkbox => CheckboxDescription::from(field).str_to_cell_data(s), + } +} + +pub(crate) fn stringify_deserialize(data: AnyData, field: &Field) -> Result { + let _ = check_type_id(&data, field)?; + let s = match field.field_type { + FieldType::RichText => RichTextDescription::from(field).str_from_cell_data(data), + FieldType::Number => NumberDescription::from(field).str_from_cell_data(data), + FieldType::DateTime => DateDescription::from(field).str_from_cell_data(data), + FieldType::SingleSelect => SingleSelectDescription::from(field).str_from_cell_data(data), + FieldType::MultiSelect => MultiSelectDescription::from(field).str_from_cell_data(data), + FieldType::Checkbox => CheckboxDescription::from(field).str_from_cell_data(data), + }; + Ok(s) +} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs new file mode 100644 index 0000000000..3870fc1359 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -0,0 +1,217 @@ +use crate::services::field::{ + CheckboxDescription, DateDescription, DateFormat, MoneySymbol, MultiSelectDescription, NumberDescription, + RichTextDescription, SelectOption, SingleSelectDescription, TimeFormat, +}; +use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; + +pub struct FieldBuilder { + field: Field, + type_options_builder: Box, +} + +impl FieldBuilder { + pub fn new(type_options_builder: T) -> Self { + let field = Field::new("Name", "", FieldType::RichText); + Self { + field, + type_options_builder: Box::new(type_options_builder), + } + } + + pub fn name(mut self, name: &str) -> Self { + self.field.name = name.to_owned(); + self + } + + pub fn desc(mut self, desc: &str) -> Self { + self.field.desc = desc.to_owned(); + self + } + + pub fn field_type(mut self, field_type: FieldType) -> Self { + self.field.field_type = field_type; + self + } + + pub fn visibility(mut self, visibility: bool) -> Self { + self.field.visibility = visibility; + self + } + + pub fn width(mut self, width: i32) -> Self { + self.field.width = width; + self + } + + pub fn frozen(mut self, frozen: bool) -> Self { + self.field.frozen = frozen; + self + } + + pub fn build(mut self) -> Field { + assert_eq!(self.field.field_type, self.type_options_builder.field_type()); + + let type_options = self.type_options_builder.build(); + self.field.type_options = type_options; + self.field + } +} + +pub trait TypeOptionsBuilder { + fn field_type(&self) -> FieldType; + fn build(&self) -> AnyData; +} + +// Text +pub struct RichTextTypeOptionsBuilder(RichTextDescription); + +impl RichTextTypeOptionsBuilder { + pub fn new() -> Self { + Self(RichTextDescription::default()) + } +} + +impl TypeOptionsBuilder for RichTextTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> AnyData { + self.0.clone().into() + } +} + +// Number +pub struct NumberTypeOptionsBuilder(NumberDescription); + +impl NumberTypeOptionsBuilder { + pub fn new() -> Self { + Self(NumberDescription::default()) + } + + pub fn name(mut self, name: &str) -> Self { + self.0.name = name.to_string(); + self + } + + pub fn set_money_symbol(mut self, money_symbol: MoneySymbol) -> Self { + self.0.set_money_symbol(money_symbol); + self + } + + pub fn scale(mut self, scale: u32) -> Self { + self.0.scale = scale; + self + } + + pub fn positive(mut self, positive: bool) -> Self { + self.0.sign_positive = positive; + self + } +} + +impl TypeOptionsBuilder for NumberTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> AnyData { + self.0.clone().into() + } +} + +// Date +pub struct DateTypeOptionsBuilder(DateDescription); +impl DateTypeOptionsBuilder { + pub fn new() -> Self { + Self(DateDescription::default()) + } + + pub fn date_format(mut self, date_format: DateFormat) -> Self { + self.0.date_format = date_format; + self + } + + pub fn time_format(mut self, time_format: TimeFormat) -> Self { + self.0.time_format = time_format; + self + } +} +impl TypeOptionsBuilder for DateTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> AnyData { + self.0.clone().into() + } +} + +// Single Select +pub struct SingleSelectTypeOptionsBuilder(SingleSelectDescription); + +impl SingleSelectTypeOptionsBuilder { + pub fn new() -> Self { + Self(SingleSelectDescription::default()) + } + + pub fn option(mut self, opt: SelectOption) -> Self { + self.0.options.push(opt); + self + } +} +impl TypeOptionsBuilder for SingleSelectTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> AnyData { + self.0.clone().into() + } +} + +// Multi Select +pub struct MultiSelectTypeOptionsBuilder(MultiSelectDescription); + +impl MultiSelectTypeOptionsBuilder { + pub fn new() -> Self { + Self(MultiSelectDescription::default()) + } + + pub fn option(mut self, opt: SelectOption) -> Self { + self.0.options.push(opt); + self + } +} + +impl TypeOptionsBuilder for MultiSelectTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> AnyData { + self.0.clone().into() + } +} + +// Checkbox +pub struct CheckboxTypeOptionsBuilder(CheckboxDescription); +impl CheckboxTypeOptionsBuilder { + pub fn new() -> Self { + Self(CheckboxDescription::default()) + } + + pub fn set_selected(mut self, is_selected: bool) -> Self { + self.0.is_selected = is_selected; + self + } +} +impl TypeOptionsBuilder for CheckboxTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> AnyData { + self.0.clone().into() + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs new file mode 100644 index 0000000000..157e5145c2 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs @@ -0,0 +1,7 @@ +mod cell_stringify; +mod field_builder; +mod type_options; + +pub use cell_stringify::*; +pub use field_builder::*; +pub use type_options::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/cell_data.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs similarity index 65% rename from frontend/rust-lib/flowy-grid/src/services/cell_data.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options.rs index ce65fb005a..1a417abe20 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell_data.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs @@ -1,5 +1,6 @@ #![allow(clippy::upper_case_acronyms)] -use crate::impl_any_data; +use crate::impl_from_and_to_type_option; +use crate::services::field::StringifyCellData; use crate::services::util::*; use bytes::Bytes; use chrono::format::strftime::StrftimeItems; @@ -15,63 +16,42 @@ use rusty_money::{ use std::str::FromStr; use strum_macros::EnumIter; -pub trait StringifyAnyData { - fn stringify_any_data(&self, data: AnyData) -> String; - fn str_to_any_data(&self, s: &str) -> Result; -} - -pub trait DisplayCell { - fn display_content(&self, s: &str) -> String; -} - #[derive(Debug, Clone, ProtoBuf, Default)] pub struct RichTextDescription { #[pb(index = 1)] pub format: String, } -impl_any_data!(RichTextDescription, FieldType::RichText); +impl_from_and_to_type_option!(RichTextDescription, FieldType::RichText); -impl StringifyAnyData for RichTextDescription { - fn stringify_any_data(&self, data: AnyData) -> String { +impl StringifyCellData for RichTextDescription { + fn str_from_cell_data(&self, data: AnyData) -> String { data.to_string() } - fn str_to_any_data(&self, s: &str) -> Result { - Ok(AnyData::from_str(&RichTextDescription::field_type(), s)) - } -} - -impl DisplayCell for RichTextDescription { - fn display_content(&self, s: &str) -> String { - s.to_string() + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(AnyData::from_str(self.field_type(), s)) } } // Checkbox -#[derive(Debug, ProtoBuf, Default)] +#[derive(Debug, Clone, ProtoBuf, Default)] pub struct CheckboxDescription { #[pb(index = 1)] pub is_selected: bool, } -impl_any_data!(CheckboxDescription, FieldType::Checkbox); +impl_from_and_to_type_option!(CheckboxDescription, FieldType::Checkbox); -impl StringifyAnyData for CheckboxDescription { - fn stringify_any_data(&self, data: AnyData) -> String { +impl StringifyCellData for CheckboxDescription { + fn str_from_cell_data(&self, data: AnyData) -> String { data.to_string() } - fn str_to_any_data(&self, s: &str) -> Result { + fn str_to_cell_data(&self, s: &str) -> Result { let s = match string_to_bool(s) { true => "1", false => "0", }; - Ok(AnyData::from_str(&CheckboxDescription::field_type(), s)) - } -} - -impl DisplayCell for CheckboxDescription { - fn display_content(&self, s: &str) -> String { - s.to_string() + Ok(AnyData::from_str(self.field_type(), s)) } } @@ -84,7 +64,7 @@ pub struct DateDescription { #[pb(index = 2)] pub time_format: TimeFormat, } -impl_any_data!(DateDescription, FieldType::DateTime); +impl_from_and_to_type_option!(DateDescription, FieldType::DateTime); impl DateDescription { fn date_time_format_str(&self) -> String { @@ -107,23 +87,8 @@ impl DateDescription { } } -impl DisplayCell for DateDescription { - fn display_content(&self, s: &str) -> String { - match s.parse::() { - Ok(timestamp) => { - let native = NaiveDateTime::from_timestamp(timestamp, 0); - self.today_from_native(native) - } - Err(e) => { - tracing::debug!("DateDescription format {} fail. error: {:?}", s, e); - String::new() - } - } - } -} - -impl StringifyAnyData for DateDescription { - fn stringify_any_data(&self, data: AnyData) -> String { +impl StringifyCellData for DateDescription { + fn str_from_cell_data(&self, data: AnyData) -> String { match String::from_utf8(data.value) { Ok(s) => match s.parse::() { Ok(timestamp) => { @@ -142,14 +107,11 @@ impl StringifyAnyData for DateDescription { } } - fn str_to_any_data(&self, s: &str) -> Result { + fn str_to_cell_data(&self, s: &str) -> Result { let timestamp = s .parse::() .map_err(|e| FlowyError::internal().context(format!("Parse {} to i64 failed: {}", s, e)))?; - Ok(AnyData::from_str( - &DateDescription::field_type(), - &format!("{}", timestamp), - )) + Ok(AnyData::from_str(self.field_type(), &format!("{}", timestamp))) } } @@ -237,54 +199,42 @@ impl std::default::Default for TimeFormat { // Single select #[derive(Clone, Debug, ProtoBuf, Default)] -pub struct SingleSelect { +pub struct SingleSelectDescription { #[pb(index = 1)] pub options: Vec, #[pb(index = 2)] pub disable_color: bool, } -impl_any_data!(SingleSelect, FieldType::SingleSelect); +impl_from_and_to_type_option!(SingleSelectDescription, FieldType::SingleSelect); -impl StringifyAnyData for SingleSelect { - fn stringify_any_data(&self, data: AnyData) -> String { +impl StringifyCellData for SingleSelectDescription { + fn str_from_cell_data(&self, data: AnyData) -> String { data.to_string() } - fn str_to_any_data(&self, s: &str) -> Result { - Ok(AnyData::from_str(&SingleSelect::field_type(), s)) - } -} - -impl DisplayCell for SingleSelect { - fn display_content(&self, s: &str) -> String { - s.to_string() + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(AnyData::from_str(self.field_type(), s)) } } // Multiple select #[derive(Clone, Debug, ProtoBuf, Default)] -pub struct MultiSelect { +pub struct MultiSelectDescription { #[pb(index = 1)] pub options: Vec, #[pb(index = 2)] pub disable_color: bool, } -impl_any_data!(MultiSelect, FieldType::MultiSelect); -impl StringifyAnyData for MultiSelect { - fn stringify_any_data(&self, data: AnyData) -> String { +impl_from_and_to_type_option!(MultiSelectDescription, FieldType::MultiSelect); +impl StringifyCellData for MultiSelectDescription { + fn str_from_cell_data(&self, data: AnyData) -> String { data.to_string() } - fn str_to_any_data(&self, s: &str) -> Result { - Ok(AnyData::from_str(&MultiSelect::field_type(), s)) - } -} - -impl DisplayCell for MultiSelect { - fn display_content(&self, s: &str) -> String { - s.to_string() + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(AnyData::from_str(self.field_type(), s)) } } @@ -314,7 +264,7 @@ impl SelectOption { #[derive(Clone, Debug, ProtoBuf)] pub struct NumberDescription { #[pb(index = 1)] - pub money: FlowyMoney, + pub money: MoneySymbol, #[pb(index = 2)] pub scale: u32, @@ -328,24 +278,26 @@ pub struct NumberDescription { #[pb(index = 5)] pub name: String, } -impl_any_data!(NumberDescription, FieldType::Number); +impl_from_and_to_type_option!(NumberDescription, FieldType::Number); impl std::default::Default for NumberDescription { fn default() -> Self { + let money = MoneySymbol::default(); + let symbol = money.symbol_str(); NumberDescription { - money: FlowyMoney::default(), + money, scale: 0, - symbol: String::new(), + symbol, sign_positive: true, - name: String::new(), + name: "Number".to_string(), } } } impl NumberDescription { - pub fn set_money(&mut self, money: FlowyMoney) { - self.money = money; - self.symbol = money.symbol(); + pub fn set_money_symbol(&mut self, money_symbol: MoneySymbol) { + self.money = money_symbol; + self.symbol = money_symbol.symbol_str(); } fn money_from_str(&self, s: &str) -> Option { @@ -368,17 +320,8 @@ impl NumberDescription { } } -impl DisplayCell for NumberDescription { - fn display_content(&self, s: &str) -> String { - match self.money_from_str(s) { - Some(money_str) => money_str, - None => String::default(), - } - } -} - -impl StringifyAnyData for NumberDescription { - fn stringify_any_data(&self, data: AnyData) -> String { +impl StringifyCellData for NumberDescription { + fn str_from_cell_data(&self, data: AnyData) -> String { match String::from_utf8(data.value) { Ok(s) => match self.money_from_str(&s) { Some(money_str) => money_str, @@ -391,47 +334,47 @@ impl StringifyAnyData for NumberDescription { } } - fn str_to_any_data(&self, s: &str) -> Result { + fn str_to_cell_data(&self, s: &str) -> Result { let strip_symbol_money = strip_money_symbol(s); let decimal = Decimal::from_str(&strip_symbol_money).map_err(|err| FlowyError::internal().context(err))?; let money_str = decimal.to_string(); - Ok(AnyData::from_str(&NumberDescription::field_type(), &money_str)) + Ok(AnyData::from_str(self.field_type(), &money_str)) } } #[derive(Clone, Copy, Debug, EnumIter, ProtoBuf_Enum)] -pub enum FlowyMoney { +pub enum MoneySymbol { CNY = 0, EUR = 1, USD = 2, } -impl std::default::Default for FlowyMoney { +impl std::default::Default for MoneySymbol { fn default() -> Self { - FlowyMoney::USD + MoneySymbol::USD } } -impl FlowyMoney { +impl MoneySymbol { // Currency list https://docs.rs/rusty-money/0.4.0/rusty_money/iso/index.html - pub fn from_symbol_str(s: &str) -> FlowyMoney { + pub fn from_symbol_str(s: &str) -> MoneySymbol { match s { - "CNY" => FlowyMoney::CNY, - "EUR" => FlowyMoney::EUR, - "USD" => FlowyMoney::USD, - _ => FlowyMoney::CNY, + "CNY" => MoneySymbol::CNY, + "EUR" => MoneySymbol::EUR, + "USD" => MoneySymbol::USD, + _ => MoneySymbol::CNY, } } - pub fn from_money(money: &rusty_money::Money) -> FlowyMoney { - FlowyMoney::from_symbol_str(&money.currency().symbol.to_string()) + pub fn from_money(money: &rusty_money::Money) -> MoneySymbol { + MoneySymbol::from_symbol_str(&money.currency().symbol.to_string()) } pub fn currency(&self) -> &'static Currency { match self { - FlowyMoney::CNY => CNY, - FlowyMoney::EUR => EUR, - FlowyMoney::USD => USD, + MoneySymbol::CNY => CNY, + MoneySymbol::EUR => EUR, + MoneySymbol::USD => USD, } } @@ -442,7 +385,7 @@ impl FlowyMoney { self.currency().iso_alpha_code.to_string() } - pub fn symbol(&self) -> String { + pub fn symbol_str(&self) -> String { self.currency().symbol.to_string() } 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 f9cf627d83..b6f55e6cfa 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -38,7 +38,7 @@ impl ClientGridEditor { ) -> FlowyResult> { let token = user.token()?; let cloud = Arc::new(GridRevisionCloudService { token }); - let grid_pad = rev_manager.load::(cloud).await?; + let grid_pad = rev_manager.load::(Some(cloud)).await?; let rev_manager = Arc::new(rev_manager); let grid_meta_pad = Arc::new(RwLock::new(grid_pad)); @@ -55,12 +55,12 @@ impl ClientGridEditor { })) } - pub async fn create_field(&mut self, field: Field) -> FlowyResult<()> { + pub async fn create_field(&self, field: Field) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.create_field(field)?)).await?; Ok(()) } - pub async fn delete_field(&mut self, field_id: &str) -> FlowyResult<()> { + pub async fn delete_field(&self, field_id: &str) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?; Ok(()) } @@ -125,6 +125,13 @@ impl ClientGridEditor { } } +#[cfg(feature = "flowy_unit_test")] +impl ClientGridEditor { + pub fn rev_manager(&self) -> Arc { + self.rev_manager.clone() + } +} + async fn load_all_fields( grid_pad: &GridMetaPad, kv_persistence: &Arc, @@ -143,7 +150,7 @@ async fn load_all_fields( Ok(map) } -struct GridPadBuilder(); +pub struct GridPadBuilder(); impl RevisionObjectBuilder for GridPadBuilder { type Output = GridMetaPad; diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs index 6704d6a718..10160e115a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs @@ -27,7 +27,7 @@ impl ClientGridBlockMetaEditor { let cloud = Arc::new(GridBlockMetaRevisionCloudService { token: token.to_owned(), }); - let block_meta_pad = rev_manager.load::(cloud).await?; + let block_meta_pad = rev_manager.load::(Some(cloud)).await?; let meta_pad = Arc::new(RwLock::new(block_meta_pad)); let rev_manager = Arc::new(rev_manager); let user_id = user_id.to_owned(); diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index 340a260b09..552f8cfe56 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -1,7 +1,6 @@ mod util; -pub mod cell_data; +pub mod field; pub mod grid_editor; pub mod grid_meta_editor; pub mod kv_persistence; -pub mod stringify; diff --git a/frontend/rust-lib/flowy-grid/src/services/stringify.rs b/frontend/rust-lib/flowy-grid/src/services/stringify.rs deleted file mode 100644 index a9154a5809..0000000000 --- a/frontend/rust-lib/flowy-grid/src/services/stringify.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::services::cell_data::*; -use crate::services::util::*; -use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; - -#[allow(dead_code)] -pub fn stringify_serialize(field: &Field, s: &str) -> Result { - match field.field_type { - FieldType::RichText => RichTextDescription::from(field).str_to_any_data(s), - FieldType::Number => NumberDescription::from(field).str_to_any_data(s), - FieldType::DateTime => DateDescription::from(field).str_to_any_data(s), - FieldType::SingleSelect => SingleSelect::from(field).str_to_any_data(s), - FieldType::MultiSelect => MultiSelect::from(field).str_to_any_data(s), - FieldType::Checkbox => CheckboxDescription::from(field).str_to_any_data(s), - } -} - -pub(crate) fn stringify_deserialize(data: AnyData, field: &Field) -> Result { - let _ = check_type_id(&data, field)?; - let s = match field.field_type { - FieldType::RichText => RichTextDescription::from(field).stringify_any_data(data), - FieldType::Number => NumberDescription::from(field).stringify_any_data(data), - FieldType::DateTime => DateDescription::from(field).stringify_any_data(data), - FieldType::SingleSelect => SingleSelect::from(field).stringify_any_data(data), - FieldType::MultiSelect => MultiSelect::from(field).stringify_any_data(data), - FieldType::Checkbox => CheckboxDescription::from(field).stringify_any_data(data), - }; - Ok(s) -} diff --git a/frontend/rust-lib/flowy-grid/src/services/util.rs b/frontend/rust-lib/flowy-grid/src/services/util.rs index 8fa196956d..a82e748a3e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/util.rs +++ b/frontend/rust-lib/flowy-grid/src/services/util.rs @@ -1,4 +1,4 @@ -use crate::services::cell_data::FlowyMoney; +use crate::services::field::MoneySymbol; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; use lazy_static::lazy_static; @@ -16,8 +16,8 @@ lazy_static! { fn generate_currency_by_symbol() -> HashMap { let mut map: HashMap = HashMap::new(); - for money in FlowyMoney::iter() { - map.insert(money.symbol(), money.currency()); + for money in MoneySymbol::iter() { + map.insert(money.symbol_str(), money.currency()); } map } @@ -25,7 +25,7 @@ fn generate_currency_by_symbol() -> HashMap { #[allow(dead_code)] pub fn string_to_money(money_str: &str) -> Option> { let mut process_money_str = String::from(money_str); - let default_currency = FlowyMoney::from_symbol_str("CNY").currency(); + let default_currency = MoneySymbol::from_symbol_str("CNY").currency(); if process_money_str.is_empty() { return None; @@ -65,7 +65,7 @@ pub fn money_from_str(s: &str) -> Option { } } decimal.set_sign_positive(true); - Some(FlowyMoney::USD.with_decimal(decimal).to_string()) + Some(MoneySymbol::USD.with_decimal(decimal).to_string()) } Err(e) => { tracing::debug!("Format {} to money failed, {:?}", s, e); diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs new file mode 100644 index 0000000000..8cf876a052 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -0,0 +1,30 @@ +use crate::services::field::*; +use flowy_collaboration::client_grid::{BuildGridInfo, GridBuilder}; +use flowy_grid_data_model::entities::{Field, FieldType}; + +pub fn make_default_grid(grid_id: &str) -> BuildGridInfo { + let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::new()) + .name("Name") + .visibility(true) + .field_type(FieldType::RichText) + .build(); + + let single_select = SingleSelectTypeOptionsBuilder::new() + .option(SelectOption::new("Done")) + .option(SelectOption::new("Progress")); + + let single_select_field = FieldBuilder::new(single_select) + .name("Name") + .visibility(true) + .field_type(FieldType::SingleSelect) + .build(); + + GridBuilder::new(grid_id) + .add_field(text_field) + .add_field(single_select_field) + .add_empty_row() + .add_empty_row() + .add_empty_row() + .build() + .unwrap() +} diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs new file mode 100644 index 0000000000..797315bb10 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -0,0 +1,16 @@ +use crate::grid::script::EditorScript::*; +use crate::grid::script::*; + +#[tokio::test] +async fn grid_creat_field_test() { + let scripts = vec![ + CreateField { + field: create_text_field(), + }, + CreateField { + field: create_single_select_field(), + }, + AssertGridMetaPad, + ]; + GridEditorTest::new().await.run_scripts(scripts).await; +} diff --git a/frontend/rust-lib/flowy-grid/tests/grid/mod.rs b/frontend/rust-lib/flowy-grid/tests/grid/mod.rs new file mode 100644 index 0000000000..04b16720e5 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/tests/grid/mod.rs @@ -0,0 +1,2 @@ +mod grid_test; +mod script; diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs new file mode 100644 index 0000000000..4e31aef2c4 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -0,0 +1,75 @@ +use flowy_grid::services::field::*; +use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; +use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; +use flowy_test::event_builder::FolderEventBuilder; +use flowy_test::helper::ViewTest; +use flowy_test::FlowySDKTest; +use std::sync::Arc; + +pub enum EditorScript { + CreateField { field: Field }, + CreateRow, + AssertGridMetaPad, +} + +pub struct GridEditorTest { + pub sdk: FlowySDKTest, + pub grid_id: String, + pub editor: Arc, +} + +impl GridEditorTest { + pub async fn new() -> Self { + let sdk = FlowySDKTest::default(); + let _ = sdk.init_user().await; + let test = ViewTest::new_grid_view(&sdk).await; + let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); + let grid_id = test.view.id; + Self { sdk, grid_id, editor } + } + + pub async fn run_scripts(&mut self, scripts: Vec) { + for script in scripts { + self.run_script(script).await; + } + } + + pub async fn run_script(&mut self, script: EditorScript) { + let grid_manager = self.sdk.grid_manager.clone(); + let pool = self.sdk.user_session.db_pool().unwrap(); + let rev_manager = self.editor.rev_manager(); + let cache = rev_manager.revision_cache().await; + + match script { + EditorScript::CreateField { field } => { + self.editor.create_field(field).await.unwrap(); + } + EditorScript::CreateRow => {} + EditorScript::AssertGridMetaPad => { + let mut grid_rev_manager = grid_manager.make_grid_rev_manager(&self.grid_id, pool.clone()).unwrap(); + let grid_pad = grid_rev_manager.load::(None).await.unwrap(); + println!("{}", grid_pad.delta_str()); + } + } + } +} + +pub fn create_text_field() -> Field { + FieldBuilder::new(RichTextTypeOptionsBuilder::new()) + .name("Name") + .visibility(true) + .field_type(FieldType::RichText) + .build() +} + +pub fn create_single_select_field() -> Field { + let single_select = SingleSelectTypeOptionsBuilder::new() + .option(SelectOption::new("Done")) + .option(SelectOption::new("Progress")); + + FieldBuilder::new(single_select) + .name("Name") + .visibility(true) + .field_type(FieldType::SingleSelect) + .build() +} diff --git a/frontend/rust-lib/flowy-grid/tests/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid_test.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/frontend/rust-lib/flowy-grid/tests/main.rs b/frontend/rust-lib/flowy-grid/tests/main.rs new file mode 100644 index 0000000000..ec055c3bb9 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/tests/main.rs @@ -0,0 +1 @@ +mod grid; diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs index e0906cc7f1..0646dbcc5b 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs @@ -1,7 +1,6 @@ use bytes::Bytes; use flowy_block::TextBlockManager; use flowy_collaboration::client_document::default::initial_quill_delta_string; -use flowy_collaboration::client_grid::make_default_grid; use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; @@ -13,6 +12,7 @@ use flowy_folder::{ manager::FolderManager, }; use flowy_grid::manager::GridManager; +use flowy_grid::util::make_default_grid; use flowy_net::ClientServerConfiguration; use flowy_net::{ http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect, diff --git a/frontend/rust-lib/flowy-sync/src/rev_manager.rs b/frontend/rust-lib/flowy-sync/src/rev_manager.rs index d0ed5240c8..7b34bb8115 100644 --- a/frontend/rust-lib/flowy-sync/src/rev_manager.rs +++ b/frontend/rust-lib/flowy-sync/src/rev_manager.rs @@ -67,14 +67,14 @@ impl RevisionManager { } } - pub async fn load(&mut self, cloud: Arc) -> FlowyResult + pub async fn load(&mut self, cloud: Option>) -> FlowyResult where B: RevisionObjectBuilder, { let (revisions, rev_id) = RevisionLoader { object_id: self.object_id.clone(), user_id: self.user_id.clone(), - cloud: Some(cloud), + cloud, rev_persistence: self.rev_persistence.clone(), } .load() diff --git a/frontend/rust-lib/flowy-test/src/helper.rs b/frontend/rust-lib/flowy-test/src/helper.rs index 83277b22c6..9c03c09bb5 100644 --- a/frontend/rust-lib/flowy-test/src/helper.rs +++ b/frontend/rust-lib/flowy-test/src/helper.rs @@ -25,11 +25,12 @@ pub struct ViewTest { } impl ViewTest { - pub async fn new(sdk: &FlowySDKTest) -> Self { + #[allow(dead_code)] + pub async fn new(sdk: &FlowySDKTest, data_type: ViewDataType) -> Self { let workspace = create_workspace(sdk, "Workspace", "").await; open_workspace(sdk, &workspace.id).await; let app = create_app(sdk, "App", "AppFlowy GitHub Project", &workspace.id).await; - let view = create_view(sdk, &app.id).await; + let view = create_view(sdk, &app.id, data_type).await; Self { sdk: sdk.clone(), workspace, @@ -37,6 +38,16 @@ impl ViewTest { view, } } + + #[allow(dead_code)] + pub async fn new_grid_view(sdk: &FlowySDKTest) -> Self { + Self::new(sdk, ViewDataType::Grid).await + } + + #[allow(dead_code)] + pub async fn new_text_block_view(sdk: &FlowySDKTest) -> Self { + Self::new(sdk, ViewDataType::TextBlock).await + } } async fn create_workspace(sdk: &FlowySDKTest, name: &str, desc: &str) -> Workspace { @@ -82,13 +93,13 @@ async fn create_app(sdk: &FlowySDKTest, name: &str, desc: &str, workspace_id: &s app } -async fn create_view(sdk: &FlowySDKTest, app_id: &str) -> View { +async fn create_view(sdk: &FlowySDKTest, app_id: &str, data_type: ViewDataType) -> View { let request = CreateViewPayload { belong_to_id: app_id.to_string(), name: "View A".to_string(), desc: "".to_string(), thumbnail: Some("http://1.png".to_string()), - data_type: ViewDataType::TextBlock, + data_type, ext_data: "".to_string(), plugin_type: 0, }; diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index dbc41e28ae..30cd8cd2e0 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -25,8 +25,7 @@ impl GridBuilder { } } - pub fn add_field(mut self, name: &str, desc: &str, field_type: FieldType) -> Self { - let field = Field::new(name, desc, field_type); + pub fn add_field(mut self, field: Field) -> Self { self.fields.push(field); self } @@ -74,27 +73,16 @@ fn check_rows(fields: &[Field], rows: &[RowMeta]) -> CollaborateResult<()> { Ok(()) } -pub fn make_default_grid(grid_id: &str) -> BuildGridInfo { - GridBuilder::new(grid_id) - .add_field("Name", "", FieldType::RichText) - .add_field("Tags", "", FieldType::SingleSelect) - .add_empty_row() - .add_empty_row() - .add_empty_row() - .build() - .unwrap() -} - #[cfg(test)] mod tests { use crate::client_grid::GridBuilder; - use flowy_grid_data_model::entities::{FieldType, GridBlockMeta, GridMeta}; + use flowy_grid_data_model::entities::{Field, FieldType, GridBlockMeta, GridMeta}; #[test] fn create_default_grid_test() { let info = GridBuilder::new("1") - .add_field("Name", "", FieldType::RichText) - .add_field("Tags", "", FieldType::SingleSelect) + .add_field(Field::new("Name", "", FieldType::RichText)) + .add_field(Field::new("Tags", "", FieldType::SingleSelect)) .add_empty_row() .add_empty_row() .add_empty_row() diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index b5cdc96e31..7c19cb40af 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -163,8 +163,19 @@ impl std::default::Default for FieldType { } } +impl AsRef for FieldType { + fn as_ref(&self) -> &FieldType { + &self + } +} + +impl Into for &FieldType { + fn into(self) -> FieldType { + self.clone() + } +} + impl FieldType { - #[allow(dead_code)] pub fn type_id(&self) -> String { let ty = self.clone(); format!("{}", ty as u8) @@ -193,13 +204,13 @@ pub struct AnyData { } impl AnyData { - pub fn from_str(field_type: &FieldType, s: &str) -> AnyData { + pub fn from_str>(field_type: F, s: &str) -> AnyData { Self::from_bytes(field_type, s.as_bytes().to_vec()) } - pub fn from_bytes>(field_type: &FieldType, bytes: T) -> AnyData { + pub fn from_bytes, F: Into>(field_type: F, bytes: T) -> AnyData { AnyData { - type_id: field_type.type_id(), + type_id: field_type.into().type_id(), value: bytes.as_ref().to_vec(), } } From baa70f2ee63f19e5818c2fee8c6813a30d2e5242 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 12 Mar 2022 22:52:24 +0800 Subject: [PATCH 15/28] chore: add grid unit test --- .../flowy-grid-data-model/meta.pb.dart | 20 +-- .../flowy-grid-data-model/meta.pbjson.dart | 8 +- frontend/rust-lib/Cargo.lock | 2 + frontend/rust-lib/flowy-block/src/lib.rs | 2 +- .../rust-lib/flowy-block/src/web_socket.rs | 4 +- .../flowy-block/tests/document/script.rs | 4 +- frontend/rust-lib/flowy-grid/Cargo.toml | 2 + .../rust-lib/flowy-grid/src/event_handler.rs | 2 +- frontend/rust-lib/flowy-grid/src/macros.rs | 16 +- .../src/services/field/field_builder.rs | 14 +- .../src/services/field/type_options.rs | 21 +-- .../flowy-grid/src/services/grid_editor.rs | 9 +- .../flowy-grid/tests/grid/grid_test.rs | 90 ++++++++++- .../rust-lib/flowy-grid/tests/grid/script.rs | 24 ++- .../src/client_grid/grid_pad.rs | 41 ++--- .../src/entities/meta.rs | 6 +- .../src/protobuf/model/meta.rs | 152 ++++++++---------- .../src/protobuf/proto/meta.proto | 4 +- 18 files changed, 252 insertions(+), 169 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 344bef10da..92532babbe 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -215,7 +215,7 @@ class Field extends $pb.GeneratedMessage { ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) - ..aOM(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', subBuilder: AnyData.create) + ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions') ..hasRequiredFields = false ; @@ -228,7 +228,7 @@ class Field extends $pb.GeneratedMessage { $core.bool? frozen, $core.bool? visibility, $core.int? width, - AnyData? typeOptions, + $core.String? typeOptions, }) { final _result = create(); if (id != null) { @@ -342,15 +342,13 @@ class Field extends $pb.GeneratedMessage { void clearWidth() => clearField(7); @$pb.TagNumber(8) - AnyData get typeOptions => $_getN(7); + $core.String get typeOptions => $_getSZ(7); @$pb.TagNumber(8) - set typeOptions(AnyData v) { setField(8, v); } + set typeOptions($core.String v) { $_setString(7, v); } @$pb.TagNumber(8) $core.bool hasTypeOptions() => $_has(7); @$pb.TagNumber(8) void clearTypeOptions() => clearField(8); - @$pb.TagNumber(8) - AnyData ensureTypeOptions() => $_ensure(7); } enum FieldChangeset_OneOfName { @@ -432,7 +430,7 @@ class FieldChangeset extends $pb.GeneratedMessage { ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) - ..aOM(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', subBuilder: AnyData.create) + ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions') ..hasRequiredFields = false ; @@ -445,7 +443,7 @@ class FieldChangeset extends $pb.GeneratedMessage { $core.bool? frozen, $core.bool? visibility, $core.int? width, - AnyData? typeOptions, + $core.String? typeOptions, }) { final _result = create(); if (fieldId != null) { @@ -580,15 +578,13 @@ class FieldChangeset extends $pb.GeneratedMessage { void clearWidth() => clearField(7); @$pb.TagNumber(8) - AnyData get typeOptions => $_getN(7); + $core.String get typeOptions => $_getSZ(7); @$pb.TagNumber(8) - set typeOptions(AnyData v) { setField(8, v); } + set typeOptions($core.String v) { $_setString(7, v); } @$pb.TagNumber(8) $core.bool hasTypeOptions() => $_has(7); @$pb.TagNumber(8) void clearTypeOptions() => clearField(8); - @$pb.TagNumber(8) - AnyData ensureTypeOptions() => $_ensure(7); } class RepeatedField extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 04e7384c15..82d830f6e1 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -69,12 +69,12 @@ const Field$json = const { const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'}, const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'}, const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'}, - const {'1': 'type_options', '3': 8, '4': 1, '5': 11, '6': '.AnyData', '10': 'typeOptions'}, + const {'1': 'type_options', '3': 8, '4': 1, '5': 9, '10': 'typeOptions'}, ], }; /// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIrCgx0eXBlX29wdGlvbnMYCCABKAsyCC5BbnlEYXRhUgt0eXBlT3B0aW9ucw=='); +final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIhCgx0eXBlX29wdGlvbnMYCCABKAlSC3R5cGVPcHRpb25z'); @$core.Deprecated('Use fieldChangesetDescriptor instead') const FieldChangeset$json = const { '1': 'FieldChangeset', @@ -86,7 +86,7 @@ const FieldChangeset$json = const { const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '9': 3, '10': 'frozen'}, const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '9': 4, '10': 'visibility'}, const {'1': 'width', '3': 7, '4': 1, '5': 5, '9': 5, '10': 'width'}, - const {'1': 'type_options', '3': 8, '4': 1, '5': 11, '6': '.AnyData', '9': 6, '10': 'typeOptions'}, + const {'1': 'type_options', '3': 8, '4': 1, '5': 9, '9': 6, '10': 'typeOptions'}, ], '8': const [ const {'1': 'one_of_name'}, @@ -100,7 +100,7 @@ const FieldChangeset$json = const { }; /// Descriptor for `FieldChangeset`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldChangesetDescriptor = $convert.base64Decode('Cg5GaWVsZENoYW5nZXNldBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBIUCgRuYW1lGAIgASgJSABSBG5hbWUSFAoEZGVzYxgDIAEoCUgBUgRkZXNjEisKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVIAlIJZmllbGRUeXBlEhgKBmZyb3plbhgFIAEoCEgDUgZmcm96ZW4SIAoKdmlzaWJpbGl0eRgGIAEoCEgEUgp2aXNpYmlsaXR5EhYKBXdpZHRoGAcgASgFSAVSBXdpZHRoEi0KDHR5cGVfb3B0aW9ucxgIIAEoCzIILkFueURhdGFIBlILdHlwZU9wdGlvbnNCDQoLb25lX29mX25hbWVCDQoLb25lX29mX2Rlc2NCEwoRb25lX29mX2ZpZWxkX3R5cGVCDwoNb25lX29mX2Zyb3plbkITChFvbmVfb2ZfdmlzaWJpbGl0eUIOCgxvbmVfb2Zfd2lkdGhCFQoTb25lX29mX3R5cGVfb3B0aW9ucw=='); +final $typed_data.Uint8List fieldChangesetDescriptor = $convert.base64Decode('Cg5GaWVsZENoYW5nZXNldBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBIUCgRuYW1lGAIgASgJSABSBG5hbWUSFAoEZGVzYxgDIAEoCUgBUgRkZXNjEisKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVIAlIJZmllbGRUeXBlEhgKBmZyb3plbhgFIAEoCEgDUgZmcm96ZW4SIAoKdmlzaWJpbGl0eRgGIAEoCEgEUgp2aXNpYmlsaXR5EhYKBXdpZHRoGAcgASgFSAVSBXdpZHRoEiMKDHR5cGVfb3B0aW9ucxgIIAEoCUgGUgt0eXBlT3B0aW9uc0INCgtvbmVfb2ZfbmFtZUINCgtvbmVfb2ZfZGVzY0ITChFvbmVfb2ZfZmllbGRfdHlwZUIPCg1vbmVfb2ZfZnJvemVuQhMKEW9uZV9vZl92aXNpYmlsaXR5Qg4KDG9uZV9vZl93aWR0aEIVChNvbmVfb2ZfdHlwZV9vcHRpb25z'); @$core.Deprecated('Use repeatedFieldDescriptor instead') const RepeatedField$json = const { '1': 'RepeatedField', diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 5ae075afa3..a4c40e1735 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1073,6 +1073,8 @@ dependencies = [ "rayon", "rust_decimal", "rusty-money", + "serde", + "serde_json", "strum", "strum_macros", "tokio", diff --git a/frontend/rust-lib/flowy-block/src/lib.rs b/frontend/rust-lib/flowy-block/src/lib.rs index b75ed7e147..b3c9de44dc 100644 --- a/frontend/rust-lib/flowy-block/src/lib.rs +++ b/frontend/rust-lib/flowy-block/src/lib.rs @@ -12,7 +12,7 @@ pub mod errors { pub use flowy_error::{internal_error, ErrorCode, FlowyError}; } -pub const DOCUMENT_SYNC_INTERVAL_IN_MILLIS: u64 = 1000; +pub const TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS: u64 = 1000; use crate::errors::FlowyError; use flowy_collaboration::entities::text_block_info::{ diff --git a/frontend/rust-lib/flowy-block/src/web_socket.rs b/frontend/rust-lib/flowy-block/src/web_socket.rs index c6033286af..7450e4a6ae 100644 --- a/frontend/rust-lib/flowy-block/src/web_socket.rs +++ b/frontend/rust-lib/flowy-block/src/web_socket.rs @@ -1,4 +1,4 @@ -use crate::{queue::EditorCommand, DOCUMENT_SYNC_INTERVAL_IN_MILLIS}; +use crate::{queue::EditorCommand, TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS}; use bytes::Bytes; use flowy_collaboration::{ entities::{ @@ -36,7 +36,7 @@ pub(crate) async fn make_block_ws_manager( RichTextConflictController::new(&user_id, resolver, Arc::new(ws_data_provider.clone()), rev_manager); let ws_data_stream = Arc::new(TextBlockRevisionWSDataStream::new(conflict_controller)); let ws_data_sink = Arc::new(TextBlockWSDataSink(ws_data_provider)); - let ping_duration = Duration::from_millis(DOCUMENT_SYNC_INTERVAL_IN_MILLIS); + let ping_duration = Duration::from_millis(TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS); let ws_manager = Arc::new(RevisionWebSocketManager::new( "Block", &doc_id, diff --git a/frontend/rust-lib/flowy-block/tests/document/script.rs b/frontend/rust-lib/flowy-block/tests/document/script.rs index 87f52a3e46..af237de010 100644 --- a/frontend/rust-lib/flowy-block/tests/document/script.rs +++ b/frontend/rust-lib/flowy-block/tests/document/script.rs @@ -1,5 +1,5 @@ use flowy_block::editor::ClientTextBlockEditor; -use flowy_block::DOCUMENT_SYNC_INTERVAL_IN_MILLIS; +use flowy_block::TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS; use flowy_sync::disk::RevisionState; use flowy_test::{helper::ViewTest, FlowySDKTest}; use lib_ot::{core::Interval, rich_text::RichTextDelta}; @@ -80,6 +80,6 @@ impl TextBlockEditorTest { assert_eq!(expected_delta, delta); } } - sleep(Duration::from_millis(DOCUMENT_SYNC_INTERVAL_IN_MILLIS)).await; + sleep(Duration::from_millis(TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS)).await; } } diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index 48c7e346a4..fda64c7f66 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -33,6 +33,8 @@ dashmap = "4.0" tokio = {version = "1", features = ["sync"]} rayon = "1.5" parking_lot = "0.11" +serde = { version = "1.0", features = ["derive"] } +serde_json = {version = "1.0"} [dev-dependencies] flowy-test = { path = "../flowy-test" } diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index b621d30a69..02f9a89206 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -35,7 +35,7 @@ pub(crate) async fn get_fields_handler( ) -> DataResult { let payload: QueryFieldPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_field = editor.get_fields(payload.field_orders).await?; + let repeated_field = editor.get_fields(Some(payload.field_orders)).await?; data_result(repeated_field) } diff --git a/frontend/rust-lib/flowy-grid/src/macros.rs b/frontend/rust-lib/flowy-grid/src/macros.rs index 9f2fedddc7..ce638f96b8 100644 --- a/frontend/rust-lib/flowy-grid/src/macros.rs +++ b/frontend/rust-lib/flowy-grid/src/macros.rs @@ -11,7 +11,7 @@ macro_rules! impl_from_field_type_option { ($target: ident) => { impl std::convert::From<&Field> for $target { fn from(field: &Field) -> $target { - match $target::try_from(Bytes::from(field.type_options.value.clone())) { + match serde_json::from_str(&field.type_options) { Ok(obj) => obj, Err(err) => { tracing::error!("{} convert from any data failed, {:?}", stringify!($target), err); @@ -32,19 +32,13 @@ macro_rules! impl_to_field_type_option { } } - impl std::convert::From<$target> for AnyData { + impl std::convert::From<$target> for String { fn from(field_description: $target) -> Self { - let field_type = field_description.field_type(); - match field_description.try_into() { - Ok(bytes) => { - let bytes: Bytes = bytes; - AnyData::from_bytes(field_type, bytes) - } + match serde_json::to_string(&field_description) { + Ok(s) => s, Err(e) => { tracing::error!("Field type data convert to AnyData fail, error: {:?}", e); - // it's impossible to fail when unwrapping the default field type data - let default_bytes: Bytes = $target::default().try_into().unwrap(); - AnyData::from_bytes(field_type, default_bytes) + serde_json::to_string(&$target::default()).unwrap() } } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index 3870fc1359..86dab02b67 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -59,7 +59,7 @@ impl FieldBuilder { pub trait TypeOptionsBuilder { fn field_type(&self) -> FieldType; - fn build(&self) -> AnyData; + fn build(&self) -> String; } // Text @@ -76,7 +76,7 @@ impl TypeOptionsBuilder for RichTextTypeOptionsBuilder { self.0.field_type() } - fn build(&self) -> AnyData { + fn build(&self) -> String { self.0.clone().into() } } @@ -115,7 +115,7 @@ impl TypeOptionsBuilder for NumberTypeOptionsBuilder { self.0.field_type() } - fn build(&self) -> AnyData { + fn build(&self) -> String { self.0.clone().into() } } @@ -142,7 +142,7 @@ impl TypeOptionsBuilder for DateTypeOptionsBuilder { self.0.field_type() } - fn build(&self) -> AnyData { + fn build(&self) -> String { self.0.clone().into() } } @@ -165,7 +165,7 @@ impl TypeOptionsBuilder for SingleSelectTypeOptionsBuilder { self.0.field_type() } - fn build(&self) -> AnyData { + fn build(&self) -> String { self.0.clone().into() } } @@ -189,7 +189,7 @@ impl TypeOptionsBuilder for MultiSelectTypeOptionsBuilder { self.0.field_type() } - fn build(&self) -> AnyData { + fn build(&self) -> String { self.0.clone().into() } } @@ -211,7 +211,7 @@ impl TypeOptionsBuilder for CheckboxTypeOptionsBuilder { self.0.field_type() } - fn build(&self) -> AnyData { + fn build(&self) -> String { self.0.clone().into() } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs index 1a417abe20..2b82d94f3a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs @@ -13,10 +13,11 @@ use rusty_money::{ iso::{Currency, CNY, EUR, USD}, Money, }; +use serde::{Deserialize, Serialize}; use std::str::FromStr; use strum_macros::EnumIter; -#[derive(Debug, Clone, ProtoBuf, Default)] +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] pub struct RichTextDescription { #[pb(index = 1)] pub format: String, @@ -34,7 +35,7 @@ impl StringifyCellData for RichTextDescription { } // Checkbox -#[derive(Debug, Clone, ProtoBuf, Default)] +#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] pub struct CheckboxDescription { #[pb(index = 1)] pub is_selected: bool, @@ -56,7 +57,7 @@ impl StringifyCellData for CheckboxDescription { } // Date -#[derive(Clone, Debug, ProtoBuf, Default)] +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] pub struct DateDescription { #[pb(index = 1)] pub date_format: DateFormat, @@ -115,7 +116,7 @@ impl StringifyCellData for DateDescription { } } -#[derive(Clone, Debug, Copy, ProtoBuf_Enum)] +#[derive(Clone, Debug, Copy, Serialize, Deserialize, ProtoBuf_Enum)] pub enum DateFormat { Local = 0, US = 1, @@ -158,7 +159,7 @@ impl DateFormat { } } -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, ProtoBuf_Enum)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize, ProtoBuf_Enum)] pub enum TimeFormat { TwelveHour = 0, TwentyFourHour = 1, @@ -198,7 +199,7 @@ impl std::default::Default for TimeFormat { } // Single select -#[derive(Clone, Debug, ProtoBuf, Default)] +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] pub struct SingleSelectDescription { #[pb(index = 1)] pub options: Vec, @@ -219,7 +220,7 @@ impl StringifyCellData for SingleSelectDescription { } // Multiple select -#[derive(Clone, Debug, ProtoBuf, Default)] +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] pub struct MultiSelectDescription { #[pb(index = 1)] pub options: Vec, @@ -238,7 +239,7 @@ impl StringifyCellData for MultiSelectDescription { } } -#[derive(Clone, Debug, ProtoBuf, Default)] +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] pub struct SelectOption { #[pb(index = 1)] pub id: String, @@ -261,7 +262,7 @@ impl SelectOption { } // Number -#[derive(Clone, Debug, ProtoBuf)] +#[derive(Clone, Debug, Serialize, Deserialize, ProtoBuf)] pub struct NumberDescription { #[pb(index = 1)] pub money: MoneySymbol, @@ -342,7 +343,7 @@ impl StringifyCellData for NumberDescription { } } -#[derive(Clone, Copy, Debug, EnumIter, ProtoBuf_Enum)] +#[derive(Clone, Copy, Debug, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] pub enum MoneySymbol { CNY = 0, EUR = 1, 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 b6f55e6cfa..9b3ce9eecf 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -9,7 +9,7 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Field, Grid, GridBlock, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, + Field, FieldChangeset, Grid, GridBlock, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, }; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_sync::{ @@ -60,6 +60,11 @@ impl ClientGridEditor { Ok(()) } + pub async fn update_field(&self, change: FieldChangeset) -> FlowyResult<()> { + let _ = self.modify(|grid| Ok(grid.update_field(change)?)).await?; + Ok(()) + } + pub async fn delete_field(&self, field_id: &str) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?; Ok(()) @@ -81,7 +86,7 @@ impl ClientGridEditor { todo!() } - pub async fn get_fields(&self, field_orders: RepeatedFieldOrder) -> FlowyResult { + pub async fn get_fields(&self, field_orders: Option) -> FlowyResult { let fields = self.grid_meta_pad.read().await.get_fields(field_orders)?; Ok(fields) } 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 797315bb10..cbdb457577 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -1,14 +1,98 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; +use flowy_grid::services::field::{SelectOption, SingleSelectDescription}; +use flowy_grid_data_model::entities::FieldChangeset; #[tokio::test] -async fn grid_creat_field_test() { +async fn default_grid_test() { + let scripts = vec![AssertFieldCount(2), AssertGridMetaPad]; + GridEditorTest::new().await.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_create_field() { + let text_field = create_text_field(); + let single_select_field = create_single_select_field(); + let scripts = vec![ + AssertFieldCount(2), + CreateField { + field: text_field.clone(), + }, + AssertFieldEqual { + field_index: 2, + field: text_field, + }, + AssertFieldCount(3), + CreateField { + field: single_select_field.clone(), + }, + AssertFieldEqual { + field_index: 3, + field: single_select_field, + }, + AssertFieldCount(4), + ]; + GridEditorTest::new().await.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_update_field_with_empty_change() { + let single_select_field = create_single_select_field(); + let change = FieldChangeset { + field_id: single_select_field.id.clone(), + name: None, + desc: None, + field_type: None, + frozen: None, + visibility: None, + width: None, + type_options: None, + }; + let scripts = vec![ CreateField { - field: create_text_field(), + field: single_select_field.clone(), }, + UpdateField { change }, + AssertFieldEqual { + field_index: 2, + field: single_select_field, + }, + ]; + GridEditorTest::new().await.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_update_field() { + let single_select_field = create_single_select_field(); + let mut cloned_field = single_select_field.clone(); + + let mut single_select_type_options = SingleSelectDescription::from(&single_select_field); + single_select_type_options.options.push(SelectOption::new("Unknown")); + + let change = FieldChangeset { + field_id: single_select_field.id.clone(), + name: None, + desc: None, + field_type: None, + frozen: Some(true), + visibility: None, + width: Some(1000), + type_options: Some(single_select_type_options.clone().into()), + }; + + cloned_field.frozen = true; + cloned_field.width = 1000; + cloned_field.type_options = single_select_type_options.into(); + + let scripts = vec![ CreateField { - field: create_single_select_field(), + field: single_select_field.clone(), + }, + UpdateField { change }, + AssertFieldEqual { + field_index: 2, + field: cloned_field, }, AssertGridMetaPad, ]; diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 4e31aef2c4..523e1d4e12 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,15 +1,21 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; -use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; +use flowy_grid_data_model::entities::{AnyData, Field, FieldChangeset, FieldType}; +use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::event_builder::FolderEventBuilder; use flowy_test::helper::ViewTest; use flowy_test::FlowySDKTest; use std::sync::Arc; +use std::time::Duration; +use tokio::time::sleep; pub enum EditorScript { CreateField { field: Field }, - CreateRow, + UpdateField { change: FieldChangeset }, + AssertFieldCount(usize), + AssertFieldEqual { field_index: usize, field: Field }, AssertGridMetaPad, + CreateRow, } pub struct GridEditorTest { @@ -44,12 +50,24 @@ impl GridEditorTest { EditorScript::CreateField { field } => { self.editor.create_field(field).await.unwrap(); } - EditorScript::CreateRow => {} + EditorScript::UpdateField { change } => { + self.editor.update_field(change).await.unwrap(); + } + EditorScript::AssertFieldCount(count) => { + assert_eq!(self.editor.get_fields(None).await.unwrap().len(), count); + } + EditorScript::AssertFieldEqual { field_index, field } => { + let repeated_fields = self.editor.get_fields(None).await.unwrap(); + let compared_field = repeated_fields[field_index].clone(); + assert_eq!(compared_field, field); + } EditorScript::AssertGridMetaPad => { + sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await; let mut grid_rev_manager = grid_manager.make_grid_rev_manager(&self.grid_id, pool.clone()).unwrap(); let grid_pad = grid_rev_manager.load::(None).await.unwrap(); println!("{}", grid_pad.delta_str()); } + EditorScript::CreateRow => {} } } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 5b99afd9c2..12d1b14c5b 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -51,25 +51,30 @@ impl GridMetaPad { }) } - pub fn get_fields(&self, field_orders: RepeatedFieldOrder) -> CollaborateResult { - let field_by_field_id = self - .grid_meta - .fields - .iter() - .map(|field| (&field.id, field)) - .collect::>(); + pub fn get_fields(&self, field_orders: Option) -> CollaborateResult { + match field_orders { + None => Ok(self.grid_meta.fields.clone().into()), + Some(field_orders) => { + let field_by_field_id = self + .grid_meta + .fields + .iter() + .map(|field| (&field.id, field)) + .collect::>(); - let fields = field_orders - .iter() - .flat_map(|field_order| match field_by_field_id.get(&field_order.field_id) { - None => { - tracing::error!("Can't find the field with id: {}", field_order.field_id); - None - } - Some(field) => Some((*field).clone()), - }) - .collect::>(); - Ok(fields.into()) + let fields = field_orders + .iter() + .flat_map(|field_order| match field_by_field_id.get(&field_order.field_id) { + None => { + tracing::error!("Can't find the field with id: {}", field_order.field_id); + None + } + Some(field) => Some((*field).clone()), + }) + .collect::>(); + Ok(fields.into()) + } + } } pub fn update_field(&mut self, change: FieldChangeset) -> CollaborateResult> { diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 7c19cb40af..8ef8df08e4 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -54,7 +54,7 @@ pub struct GridBlockMeta { pub rows: Vec, } -#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf, PartialEq, Eq)] pub struct Field { #[pb(index = 1)] pub id: String, @@ -78,7 +78,7 @@ pub struct Field { pub width: i32, #[pb(index = 8)] - pub type_options: AnyData, + pub type_options: String, } impl Field { @@ -120,7 +120,7 @@ pub struct FieldChangeset { pub width: Option, #[pb(index = 8, one_of)] - pub type_options: Option, + pub type_options: Option, } #[derive(Debug, Default, ProtoBuf)] diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index 4cb13bf25e..cd222c2868 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -727,7 +727,7 @@ pub struct Field { pub frozen: bool, pub visibility: bool, pub width: i32, - pub type_options: ::protobuf::SingularPtrField, + pub type_options: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -882,47 +882,35 @@ impl Field { self.width = v; } - // .AnyData type_options = 8; + // string type_options = 8; - pub fn get_type_options(&self) -> &AnyData { - self.type_options.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_type_options(&self) -> &str { + &self.type_options } pub fn clear_type_options(&mut self) { self.type_options.clear(); } - pub fn has_type_options(&self) -> bool { - self.type_options.is_some() - } - // Param is passed by value, moved - pub fn set_type_options(&mut self, v: AnyData) { - self.type_options = ::protobuf::SingularPtrField::some(v); + pub fn set_type_options(&mut self, v: ::std::string::String) { + self.type_options = v; } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_type_options(&mut self) -> &mut AnyData { - if self.type_options.is_none() { - self.type_options.set_default(); - } - self.type_options.as_mut().unwrap() + pub fn mut_type_options(&mut self) -> &mut ::std::string::String { + &mut self.type_options } // Take field - pub fn take_type_options(&mut self) -> AnyData { - self.type_options.take().unwrap_or_else(|| AnyData::new()) + pub fn take_type_options(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.type_options, ::std::string::String::new()) } } impl ::protobuf::Message for Field { fn is_initialized(&self) -> bool { - for v in &self.type_options { - if !v.is_initialized() { - return false; - } - }; true } @@ -964,7 +952,7 @@ impl ::protobuf::Message for Field { self.width = tmp; }, 8 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.type_options)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.type_options)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -999,9 +987,8 @@ impl ::protobuf::Message for Field { if self.width != 0 { my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint); } - if let Some(ref v) = self.type_options.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + if !self.type_options.is_empty() { + my_size += ::protobuf::rt::string_size(8, &self.type_options); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -1030,10 +1017,8 @@ impl ::protobuf::Message for Field { if self.width != 0 { os.write_int32(7, self.width)?; } - if let Some(ref v) = self.type_options.as_ref() { - os.write_tag(8, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; + if !self.type_options.is_empty() { + os.write_string(8, &self.type_options)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -1108,7 +1093,7 @@ impl ::protobuf::Message for Field { |m: &Field| { &m.width }, |m: &mut Field| { &mut m.width }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "type_options", |m: &Field| { &m.type_options }, |m: &mut Field| { &mut m.type_options }, @@ -1208,7 +1193,7 @@ pub enum FieldChangeset_oneof_one_of_width { #[derive(Clone,PartialEq,Debug)] pub enum FieldChangeset_oneof_one_of_type_options { - type_options(AnyData), + type_options(::std::string::String), } impl FieldChangeset { @@ -1440,13 +1425,13 @@ impl FieldChangeset { self.one_of_width = ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(v)) } - // .AnyData type_options = 8; + // string type_options = 8; - pub fn get_type_options(&self) -> &AnyData { + pub fn get_type_options(&self) -> &str { match self.one_of_type_options { ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(ref v)) => v, - _ => ::default_instance(), + _ => "", } } pub fn clear_type_options(&mut self) { @@ -1461,15 +1446,15 @@ impl FieldChangeset { } // Param is passed by value, moved - pub fn set_type_options(&mut self, v: AnyData) { + pub fn set_type_options(&mut self, v: ::std::string::String) { self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(v)) } // Mutable pointer to the field. - pub fn mut_type_options(&mut self) -> &mut AnyData { + pub fn mut_type_options(&mut self) -> &mut ::std::string::String { if let ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(_)) = self.one_of_type_options { } else { - self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(AnyData::new())); + self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(::std::string::String::new())); } match self.one_of_type_options { ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(ref mut v)) => v, @@ -1478,25 +1463,20 @@ impl FieldChangeset { } // Take field - pub fn take_type_options(&mut self) -> AnyData { + pub fn take_type_options(&mut self) -> ::std::string::String { if self.has_type_options() { match self.one_of_type_options.take() { ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(v)) => v, _ => panic!(), } } else { - AnyData::new() + ::std::string::String::new() } } } impl ::protobuf::Message for FieldChangeset { fn is_initialized(&self) -> bool { - if let Some(FieldChangeset_oneof_one_of_type_options::type_options(ref v)) = self.one_of_type_options { - if !v.is_initialized() { - return false; - } - } true } @@ -1547,7 +1527,7 @@ impl ::protobuf::Message for FieldChangeset { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(is.read_message()?)); + self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(is.read_string()?)); }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -1609,8 +1589,7 @@ impl ::protobuf::Message for FieldChangeset { if let ::std::option::Option::Some(ref v) = self.one_of_type_options { match v { &FieldChangeset_oneof_one_of_type_options::type_options(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + my_size += ::protobuf::rt::string_size(8, &v); }, }; } @@ -1668,9 +1647,7 @@ impl ::protobuf::Message for FieldChangeset { if let ::std::option::Option::Some(ref v) = self.one_of_type_options { match v { &FieldChangeset_oneof_one_of_type_options::type_options(ref v) => { - os.write_tag(8, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; + os.write_string(8, v)?; }, }; } @@ -1747,7 +1724,7 @@ impl ::protobuf::Message for FieldChangeset { FieldChangeset::has_width, FieldChangeset::get_width, )); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, AnyData>( + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( "type_options", FieldChangeset::has_type_options, FieldChangeset::get_type_options, @@ -3183,46 +3160,45 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ndex\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\ \x20\x01(\x05R\x08rowCount\"H\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\ \x01\x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.\ - RowMetaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\t\ + RowMetaR\x04rows\"\xdb\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\t\ R\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\ FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ - idth\x18\x07\x20\x01(\x05R\x05width\x12+\n\x0ctype_options\x18\x08\x20\ - \x01(\x0b2\x08.AnyDataR\x0btypeOptions\"\x87\x03\n\x0eFieldChangeset\x12\ - \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04name\x18\ - \x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\ - \x04desc\x12+\n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeH\x02R\tfie\ - ldType\x12\x18\n\x06frozen\x18\x05\x20\x01(\x08H\x03R\x06frozen\x12\x20\ - \n\nvisibility\x18\x06\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\ - \x18\x07\x20\x01(\x05H\x05R\x05width\x12-\n\x0ctype_options\x18\x08\x20\ - \x01(\x0b2\x08.AnyDataH\x06R\x0btypeOptionsB\r\n\x0bone_of_nameB\r\n\x0b\ - one_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11\ - one_of_visibilityB\x0e\n\x0cone_of_widthB\x15\n\x13one_of_type_options\"\ - -\n\rRepeatedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\ - \x05items\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06ty\ - peId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07Ro\ - wMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\ - \x18\x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\ - \x03(\x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06h\ - eight\x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\ - \x01(\x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\ - \x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellM\ - etaR\x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row\ - _id\x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\ - \x05H\0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvis\ - ibility\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChanges\ - et.CellByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\ - \x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\ - \x01(\x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\ - \x11one_of_visibility\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\ - \x20\x01(\tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\ - \x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\ - \x04\x20\x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\ - \x01(\x05R\x06height*d\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\ - \x05b\x06proto3\ + idth\x18\x07\x20\x01(\x05R\x05width\x12!\n\x0ctype_options\x18\x08\x20\ + \x01(\tR\x0btypeOptions\"\xfd\x02\n\x0eFieldChangeset\x12\x19\n\x08field\ + _id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04name\x18\x02\x20\x01(\tH\ + \0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12+\n\nf\ + ield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\ + \x06frozen\x18\x05\x20\x01(\x08H\x03R\x06frozen\x12\x20\n\nvisibility\ + \x18\x06\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\x18\x07\x20\ + \x01(\x05H\x05R\x05width\x12#\n\x0ctype_options\x18\x08\x20\x01(\tH\x06R\ + \x0btypeOptionsB\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\x0c\ + one_of_widthB\x15\n\x13one_of_type_options\"-\n\rRepeatedField\x12\x1c\n\ + \x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"8\n\x07AnyData\x12\ + \x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\ + \x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\ + \x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07bloc\ + kId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByF\ + ieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\ + \x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\ + \n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\ + \x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\ + \xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\ + \x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\ + \n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_\ + field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rce\ + llByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\ + \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\ + value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"\x82\ + \x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\ + \x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\ + \x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\x08.AnyD\ + ataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06height*d\n\tFi\ + eldType\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\x0bMult\ + iSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 43c7e67d76..503284f7b5 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -22,7 +22,7 @@ message Field { bool frozen = 5; bool visibility = 6; int32 width = 7; - AnyData type_options = 8; + string type_options = 8; } message FieldChangeset { string field_id = 1; @@ -32,7 +32,7 @@ message FieldChangeset { oneof one_of_frozen { bool frozen = 5; }; oneof one_of_visibility { bool visibility = 6; }; oneof one_of_width { int32 width = 7; }; - oneof one_of_type_options { AnyData type_options = 8; }; + oneof one_of_type_options { string type_options = 8; }; } message RepeatedField { repeated Field items = 1; From 572e38ec1c979cf6eb35db3acd9b982dd36fb780 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 13 Mar 2022 11:06:28 +0800 Subject: [PATCH 16/28] chore: config grid row changeset --- .../flowy-grid-data-model/grid.pb.dart | 48 ++--- .../flowy-grid-data-model/grid.pbjson.dart | 10 +- .../flowy-grid-data-model/meta.pb.dart | 66 +----- .../flowy-grid-data-model/meta.pbjson.dart | 9 +- .../rust-lib/flowy-grid/src/event_handler.rs | 4 +- .../flowy-grid/src/services/field/mod.rs | 2 - .../src/services/field/type_options.rs | 2 +- .../flowy-grid/src/services/grid_editor.rs | 139 ++++--------- .../src/services/grid_meta_editor.rs | 114 ++++++++++- .../rust-lib/flowy-grid/src/services/mod.rs | 1 + .../services/{field => row}/cell_stringify.rs | 0 .../flowy-grid/src/services/row/mod.rs | 7 + .../src/services/row/row_builder.rs | 24 +++ .../flowy-grid/src/services/row/row_loader.rs | 68 +++++++ .../flowy-grid/tests/grid/grid_test.rs | 76 ++++++- .../rust-lib/flowy-grid/tests/grid/script.rs | 35 +++- .../src/client_grid/block_pad.rs | 4 + .../src/client_grid/grid_builder.rs | 2 +- .../src/client_grid/grid_pad.rs | 27 ++- .../src/entities/grid.rs | 13 +- .../src/entities/meta.rs | 47 +++-- .../src/protobuf/model/grid.rs | 120 +++++------ .../src/protobuf/model/meta.rs | 188 +++--------------- .../src/protobuf/proto/grid.proto | 6 +- .../src/protobuf/proto/meta.proto | 7 +- 25 files changed, 555 insertions(+), 464 deletions(-) rename frontend/rust-lib/flowy-grid/src/services/{field => row}/cell_stringify.rs (100%) create mode 100644 frontend/rust-lib/flowy-grid/src/services/row/mod.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs 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 c853bb867b..4122de9503 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 @@ -163,17 +163,22 @@ class RepeatedFieldOrder extends $pb.GeneratedMessage { class RowOrder extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowOrder', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') ..hasRequiredFields = false ; RowOrder._() : super(); factory RowOrder({ $core.String? rowId, + $core.String? blockId, }) { final _result = create(); if (rowId != null) { _result.rowId = rowId; } + if (blockId != null) { + _result.blockId = blockId; + } return _result; } factory RowOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -205,6 +210,15 @@ class RowOrder extends $pb.GeneratedMessage { $core.bool hasRowId() => $_has(0); @$pb.TagNumber(1) void clearRowId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get blockId => $_getSZ(1); + @$pb.TagNumber(2) + set blockId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasBlockId() => $_has(1); + @$pb.TagNumber(2) + void clearBlockId() => clearField(2); } class RepeatedRowOrder extends $pb.GeneratedMessage { @@ -360,22 +374,17 @@ class RepeatedRow 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') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'content') + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'content') ..hasRequiredFields = false ; Cell._() : super(); factory Cell({ - $core.String? id, $core.String? fieldId, $core.String? content, }) { final _result = create(); - if (id != null) { - _result.id = id; - } if (fieldId != null) { _result.fieldId = fieldId; } @@ -406,31 +415,22 @@ class Cell extends $pb.GeneratedMessage { static Cell? _defaultInstance; @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); + $core.String get fieldId => $_getSZ(0); @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } + set fieldId($core.String v) { $_setString(0, v); } @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); + $core.bool hasFieldId() => $_has(0); @$pb.TagNumber(1) - void clearId() => clearField(1); + void clearFieldId() => clearField(1); @$pb.TagNumber(2) - $core.String get fieldId => $_getSZ(1); + $core.String get content => $_getSZ(1); @$pb.TagNumber(2) - set fieldId($core.String v) { $_setString(1, v); } + set content($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasFieldId() => $_has(1); + $core.bool hasContent() => $_has(1); @$pb.TagNumber(2) - void clearFieldId() => clearField(2); - - @$pb.TagNumber(3) - $core.String get content => $_getSZ(2); - @$pb.TagNumber(3) - set content($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasContent() => $_has(2); - @$pb.TagNumber(3) - void clearContent() => clearField(3); + void clearContent() => clearField(2); } class CreateGridPayload 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 96bfd55dfd..2c1a16296d 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 @@ -45,11 +45,12 @@ const RowOrder$json = const { '1': 'RowOrder', '2': const [ const {'1': 'row_id', '3': 1, '4': 1, '5': 9, '10': 'rowId'}, + const {'1': 'block_id', '3': 2, '4': 1, '5': 9, '10': 'blockId'}, ], }; /// Descriptor for `RowOrder`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rowOrderDescriptor = $convert.base64Decode('CghSb3dPcmRlchIVCgZyb3dfaWQYASABKAlSBXJvd0lk'); +final $typed_data.Uint8List rowOrderDescriptor = $convert.base64Decode('CghSb3dPcmRlchIVCgZyb3dfaWQYASABKAlSBXJvd0lkEhkKCGJsb2NrX2lkGAIgASgJUgdibG9ja0lk'); @$core.Deprecated('Use repeatedRowOrderDescriptor instead') const RepeatedRowOrder$json = const { '1': 'RepeatedRowOrder', @@ -97,14 +98,13 @@ final $typed_data.Uint8List repeatedRowDescriptor = $convert.base64Decode('CgtSZ const Cell$json = const { '1': 'Cell', '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'content', '3': 3, '4': 1, '5': 9, '10': 'content'}, + const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'content', '3': 2, '4': 1, '5': 9, '10': 'content'}, ], }; /// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEg4KAmlkGAEgASgJUgJpZBIZCghmaWVsZF9pZBgCIAEoCVIHZmllbGRJZBIYCgdjb250ZW50GAMgASgJUgdjb250ZW50'); +final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhgKB2NvbnRlbnQYAiABKAlSB2NvbnRlbnQ='); @$core.Deprecated('Use createGridPayloadDescriptor instead') const CreateGridPayload$json = const { '1': 'CreateGridPayload', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 92532babbe..25104afa46 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -897,38 +897,23 @@ class RowMetaChangeset extends $pb.GeneratedMessage { class CellMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellMeta', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOM(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: AnyData.create) - ..a<$core.int>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') ..hasRequiredFields = false ; CellMeta._() : super(); factory CellMeta({ - $core.String? id, - $core.String? rowId, $core.String? fieldId, - AnyData? data, - $core.int? height, + $core.String? data, }) { final _result = create(); - if (id != null) { - _result.id = id; - } - if (rowId != null) { - _result.rowId = rowId; - } if (fieldId != null) { _result.fieldId = fieldId; } if (data != null) { _result.data = data; } - if (height != null) { - _result.height = height; - } return _result; } factory CellMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -953,50 +938,21 @@ class CellMeta extends $pb.GeneratedMessage { static CellMeta? _defaultInstance; @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); + $core.String get fieldId => $_getSZ(0); @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } + set fieldId($core.String v) { $_setString(0, v); } @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); + $core.bool hasFieldId() => $_has(0); @$pb.TagNumber(1) - void clearId() => clearField(1); + void clearFieldId() => clearField(1); @$pb.TagNumber(2) - $core.String get rowId => $_getSZ(1); + $core.String get data => $_getSZ(1); @$pb.TagNumber(2) - set rowId($core.String v) { $_setString(1, v); } + set data($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasRowId() => $_has(1); + $core.bool hasData() => $_has(1); @$pb.TagNumber(2) - void clearRowId() => clearField(2); - - @$pb.TagNumber(3) - $core.String get fieldId => $_getSZ(2); - @$pb.TagNumber(3) - set fieldId($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasFieldId() => $_has(2); - @$pb.TagNumber(3) - void clearFieldId() => clearField(3); - - @$pb.TagNumber(4) - AnyData get data => $_getN(3); - @$pb.TagNumber(4) - set data(AnyData v) { setField(4, v); } - @$pb.TagNumber(4) - $core.bool hasData() => $_has(3); - @$pb.TagNumber(4) - void clearData() => clearField(4); - @$pb.TagNumber(4) - AnyData ensureData() => $_ensure(3); - - @$pb.TagNumber(5) - $core.int get height => $_getIZ(4); - @$pb.TagNumber(5) - set height($core.int v) { $_setSignedInt32(4, v); } - @$pb.TagNumber(5) - $core.bool hasHeight() => $_has(4); - @$pb.TagNumber(5) - void clearHeight() => clearField(5); + void clearData() => clearField(2); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 82d830f6e1..322b477e30 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -179,13 +179,10 @@ final $typed_data.Uint8List rowMetaChangesetDescriptor = $convert.base64Decode(' const CellMeta$json = const { '1': 'CellMeta', '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, - const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'data', '3': 4, '4': 1, '5': 11, '6': '.AnyData', '10': 'data'}, - const {'1': 'height', '3': 5, '4': 1, '5': 5, '10': 'height'}, + const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'data', '3': 2, '4': 1, '5': 9, '10': 'data'}, ], }; /// Descriptor for `CellMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellMetaDescriptor = $convert.base64Decode('CghDZWxsTWV0YRIOCgJpZBgBIAEoCVICaWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIZCghmaWVsZF9pZBgDIAEoCVIHZmllbGRJZBIcCgRkYXRhGAQgASgLMgguQW55RGF0YVIEZGF0YRIWCgZoZWlnaHQYBSABKAVSBmhlaWdodA=='); +final $typed_data.Uint8List cellMetaDescriptor = $convert.base64Decode('CghDZWxsTWV0YRIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBISCgRkYXRhGAIgASgJUgRkYXRh'); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 02f9a89206..0861f2aaa1 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -24,7 +24,7 @@ pub(crate) async fn get_rows_handler( ) -> DataResult { let payload: QueryRowPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_row = editor.get_rows(payload.row_orders).await?; + let repeated_row: RepeatedRow = editor.get_rows(Some(payload.row_orders)).await?.into(); data_result(repeated_row) } @@ -35,7 +35,7 @@ pub(crate) async fn get_fields_handler( ) -> DataResult { let payload: QueryFieldPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_field = editor.get_fields(Some(payload.field_orders)).await?; + let repeated_field: RepeatedField = editor.get_fields(Some(payload.field_orders)).await?.into(); data_result(repeated_field) } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs index 157e5145c2..61b5889e68 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs @@ -1,7 +1,5 @@ -mod cell_stringify; mod field_builder; mod type_options; -pub use cell_stringify::*; pub use field_builder::*; pub use type_options::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs index 2b82d94f3a..b192a1e118 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs @@ -1,6 +1,6 @@ #![allow(clippy::upper_case_acronyms)] use crate::impl_from_and_to_type_option; -use crate::services::field::StringifyCellData; +use crate::services::row::StringifyCellData; use crate::services::util::*; use bytes::Bytes; use chrono::format::strftime::StrftimeItems; 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 9b3ce9eecf..4b7250079e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,7 +1,7 @@ use crate::manager::GridUser; use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; -use crate::services::grid_meta_editor::ClientGridBlockMetaEditor; +use crate::services::grid_meta_editor::{ClientGridBlockMetaEditor, GridBlockMetaEditorManager}; use bytes::Bytes; use dashmap::DashMap; use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; @@ -9,7 +9,8 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Field, FieldChangeset, Grid, GridBlock, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, + Field, FieldChangeset, Grid, GridBlock, GridBlockChangeset, RepeatedField, RepeatedFieldOrder, RepeatedRow, + RepeatedRowOrder, Row, }; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_sync::{ @@ -43,7 +44,7 @@ impl ClientGridEditor { let grid_meta_pad = Arc::new(RwLock::new(grid_pad)); let block_meta_manager = - Arc::new(GridBlockMetaEditorManager::new(&user, grid_meta_pad.read().await.get_blocks()).await?); + Arc::new(GridBlockMetaEditorManager::new(&user, grid_meta_pad.read().await.get_blocks().clone()).await?); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), @@ -70,27 +71,60 @@ impl ClientGridEditor { Ok(()) } + pub async fn create_block(&self, grid_block: GridBlock) -> FlowyResult<()> { + let _ = self.modify(|grid| Ok(grid.create_block(grid_block)?)).await?; + Ok(()) + } + + pub async fn update_block(&self, change: GridBlockChangeset) -> FlowyResult<()> { + let _ = self.modify(|grid| Ok(grid.update_block(change)?)).await?; + Ok(()) + } + pub async fn create_row(&self) -> FlowyResult<()> { - todo!() + let fields = self.grid_meta_pad.read().await.get_fields(None)?; + match self.grid_meta_pad.read().await.get_blocks().last() { + None => Err(FlowyError::internal().context("There is no grid block in this grid")), + Some(grid_block) => { + let row_count = self.block_meta_manager.create_row(fields, grid_block).await?; + let change = GridBlockChangeset::from_row_count(&grid_block.id, row_count); + let _ = self.update_block(change).await?; + Ok(()) + } + } } - pub async fn get_rows(&self, _row_orders: RepeatedRowOrder) -> FlowyResult { - todo!() + pub async fn get_rows(&self, row_orders: Option) -> FlowyResult> { + let fields = self.grid_meta_pad.read().await.get_fields(None)?; + let rows = self.block_meta_manager.get_rows(fields, row_orders).await?; + Ok(rows) } - pub async fn delete_rows(&self, _ids: Vec) -> FlowyResult<()> { - todo!() + pub async fn delete_rows(&self, row_orders: Option) -> FlowyResult<()> { + let row_counts = self.block_meta_manager.delete_rows(row_orders).await?; + for (block_id, row_count) in row_counts { + let _ = self + .update_block(GridBlockChangeset::from_row_count(&block_id, row_count)) + .await?; + } + + Ok(()) } pub async fn grid_data(&self) -> Grid { todo!() } - pub async fn get_fields(&self, field_orders: Option) -> FlowyResult { + pub async fn get_fields(&self, field_orders: Option) -> FlowyResult> { let fields = self.grid_meta_pad.read().await.get_fields(field_orders)?; Ok(fields) } + pub async fn get_blocks(&self) -> FlowyResult> { + let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); + Ok(grid_blocks) + } + pub async fn delta_str(&self) -> String { self.grid_meta_pad.read().await.delta_str() } @@ -184,90 +218,3 @@ impl RevisionCompactor for GridRevisionCompactor { Ok(delta.to_bytes()) } } - -struct GridBlockMetaEditorManager { - editor_map: DashMap>, -} - -impl GridBlockMetaEditorManager { - async fn new(user: &Arc, blocks: Vec) -> FlowyResult { - let editor_map = make_block_meta_editor_map(user, blocks).await?; - let manager = Self { editor_map }; - Ok(manager) - } - - async fn get_editor(&self, _block_id: &str) -> Arc { - todo!() - } - - pub async fn get_rows(&self, _row_orders: RepeatedRowOrder) -> FlowyResult { - // let ids = row_orders - // .items - // .into_iter() - // .map(|row_order| row_order.row_id) - // .collect::>(); - // let row_metas: Vec = self.kv_persistence.batch_get(ids)?; - // - // let make_cell = |field_id: String, raw_cell: CellMeta| { - // let some_field = self.field_map.get(&field_id); - // if some_field.is_none() { - // tracing::error!("Can't find the field with {}", field_id); - // return None; - // } - // self.cell_map.insert(raw_cell.id.clone(), raw_cell.clone()); - // - // let field = some_field.unwrap(); - // match stringify_deserialize(raw_cell.data, field.value()) { - // Ok(content) => { - // let cell = Cell { - // id: raw_cell.id, - // field_id: field_id.clone(), - // content, - // }; - // Some((field_id, cell)) - // } - // Err(_) => None, - // } - // }; - // - // let rows = row_metas - // .into_par_iter() - // .map(|row_meta| { - // let mut row = Row { - // id: row_meta.id.clone(), - // cell_by_field_id: Default::default(), - // height: row_meta.height, - // }; - // row.cell_by_field_id = row_meta - // .cell_by_field_id - // .into_par_iter() - // .flat_map(|(field_id, raw_cell)| make_cell(field_id, raw_cell)) - // .collect::>(); - // row - // }) - // .collect::>(); - // - // Ok(rows.into()) - todo!() - } -} - -async fn make_block_meta_editor_map( - user: &Arc, - blocks: Vec, -) -> FlowyResult>> { - let token = user.token()?; - let user_id = user.user_id()?; - let pool = user.db_pool()?; - - let editor_map = DashMap::new(); - for block in blocks { - let disk_cache = Arc::new(SQLiteGridBlockMetaRevisionPersistence::new(&user_id, pool.clone())); - let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, &block.id, disk_cache)); - let rev_manager = RevisionManager::new(&user_id, &block.id, rev_persistence); - let editor = ClientGridBlockMetaEditor::new(&user_id, &token, &block.id, rev_manager).await?; - editor_map.insert(block.id, Arc::new(editor)); - } - - Ok(editor_map) -} diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs index 10160e115a..5358b4cde5 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs @@ -1,15 +1,110 @@ +use crate::manager::GridUser; +use crate::services::row::{make_row_ids_per_block, make_rows, sort_rows, RowBuilder}; use bytes::Bytes; +use dashmap::mapref::one::Ref; +use dashmap::DashMap; use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset}; -use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; +use flowy_grid_data_model::entities::{ + Field, GridBlock, RepeatedRow, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, +}; +use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; +use flowy_sync::{ + RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, +}; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; +use lib_sqlite::ConnectionPool; +use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; +pub(crate) struct GridBlockMetaEditorManager { + user: Arc, + editor_map: DashMap>, +} + +impl GridBlockMetaEditorManager { + pub(crate) async fn new(user: &Arc, blocks: Vec) -> FlowyResult { + let editor_map = make_block_meta_editor_map(user, blocks).await?; + let user = user.clone(); + let manager = Self { user, editor_map }; + Ok(manager) + } + + pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult> { + match self.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()); + Ok(editor) + } + Some(editor) => Ok(editor.clone()), + } + } + + pub(crate) async fn create_row(&self, fields: Vec, grid_block: &GridBlock) -> FlowyResult { + let row = RowBuilder::new(&fields, &grid_block.id).build(); + let editor = self.get_editor(&grid_block.id).await?; + editor.create_row(row).await + } + + pub(crate) async fn delete_rows(&self, row_orders: Option) -> FlowyResult> { + Ok(vec![("".to_owned(), 2)]) + } + + pub(crate) async fn get_rows( + &self, + fields: Vec, + row_orders: Option, + ) -> FlowyResult> { + match row_orders { + None => { + let rows = vec![]; + Ok(rows) + } + Some(row_orders) => { + let row_ids_per_blocks = make_row_ids_per_block(&row_orders); + let mut rows = vec![]; + for row_ids_per_block in row_ids_per_blocks { + let editor = self.get_editor(&row_ids_per_block.block_id).await?; + let row_metas = editor.get_rows(row_ids_per_block.row_ids).await?; + rows.extend(make_rows(&fields, row_metas)); + } + sort_rows(&mut rows, row_orders); + Ok(rows) + } + } + } +} + +async fn make_block_meta_editor_map( + user: &Arc, + blocks: Vec, +) -> FlowyResult>> { + let editor_map = DashMap::new(); + for block in blocks { + let editor = make_block_meta_editor(user, &block.id).await?; + editor_map.insert(block.id, Arc::new(editor)); + } + + Ok(editor_map) +} + +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()?; + + 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 +} + pub struct ClientGridBlockMetaEditor { user_id: String, pub block_id: String, @@ -40,10 +135,17 @@ impl ClientGridBlockMetaEditor { }) } - async fn create_row(&self) -> FlowyResult<()> { - let row = RowMeta::new(&self.block_id, vec![]); - let _ = self.modify(|pad| Ok(pad.add_row(row)?)).await?; - Ok(()) + async fn create_row(&self, row: RowMeta) -> FlowyResult { + let mut row_count = 0; + let _ = self + .modify(|pad| { + let change = pad.add_row(row)?; + row_count = pad.number_of_rows(); + Ok(change) + }) + .await?; + + Ok(row_count) } pub async fn delete_rows(&self, ids: Vec) -> FlowyResult<()> { diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index 552f8cfe56..0a7918b5d6 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -4,3 +4,4 @@ pub mod field; pub mod grid_editor; pub mod grid_meta_editor; pub mod kv_persistence; +pub mod row; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/cell_stringify.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs similarity index 100% rename from frontend/rust-lib/flowy-grid/src/services/field/cell_stringify.rs rename to frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs diff --git a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs new file mode 100644 index 0000000000..baac627e00 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs @@ -0,0 +1,7 @@ +mod cell_stringify; +mod row_builder; +mod row_loader; + +pub use cell_stringify::*; +pub use row_builder::*; +pub use row_loader::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs new file mode 100644 index 0000000000..d88b580788 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -0,0 +1,24 @@ +use flowy_grid_data_model::entities::{CellMeta, Field, RowMeta}; + +pub struct RowBuilder<'a> { + fields: &'a Vec, + row: RowMeta, +} + +impl<'a> RowBuilder<'a> { + pub fn new(fields: &'a Vec, block_id: &'a String) -> Self { + let row = RowMeta::new(block_id); + Self { fields, row } + } + + #[allow(dead_code)] + pub fn add_cell(mut self, field_id: &str, data: String) -> Self { + let cell = CellMeta::new(field_id, data); + self.row.cell_by_field_id.insert(field_id.to_owned(), cell); + self + } + + pub fn build(self) -> RowMeta { + self.row + } +} 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 new file mode 100644 index 0000000000..f9092a5d89 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -0,0 +1,68 @@ +use flowy_grid_data_model::entities::{Field, RepeatedRowOrder, Row, RowMeta}; +use std::collections::HashMap; + +pub(crate) struct RowIdsPerBlock { + pub(crate) block_id: String, + pub(crate) row_ids: Vec, +} + +pub(crate) fn make_row_ids_per_block(row_orders: &RepeatedRowOrder) -> Vec { + let mut map: HashMap = HashMap::new(); + row_orders.iter().for_each(|row_order| { + let block_id = row_order.block_id.clone(); + let entry = map.entry(block_id.clone()).or_insert(RowIdsPerBlock { + block_id, + row_ids: vec![], + }); + entry.row_ids.push(row_order.row_id.clone()); + }); + map.into_values().collect::>() +} + +pub(crate) fn sort_rows(rows: &mut Vec, row_orders: RepeatedRowOrder) { + todo!() +} + +pub(crate) fn make_rows(fields: &Vec, rows: Vec) -> Vec { + // let make_cell = |field_id: String, raw_cell: CellMeta| { + // let some_field = self.field_map.get(&field_id); + // if some_field.is_none() { + // tracing::error!("Can't find the field with {}", field_id); + // return None; + // } + // self.cell_map.insert(raw_cell.id.clone(), raw_cell.clone()); + // + // let field = some_field.unwrap(); + // match stringify_deserialize(raw_cell.data, field.value()) { + // Ok(content) => { + // let cell = Cell { + // id: raw_cell.id, + // field_id: field_id.clone(), + // content, + // }; + // Some((field_id, cell)) + // } + // Err(_) => None, + // } + // }; + // + // let rows = row_metas + // .into_par_iter() + // .map(|row_meta| { + // let mut row = Row { + // id: row_meta.id.clone(), + // cell_by_field_id: Default::default(), + // height: row_meta.height, + // }; + // row.cell_by_field_id = row_meta + // .cell_by_field_id + // .into_par_iter() + // .flat_map(|(field_id, raw_cell)| make_cell(field_id, raw_cell)) + // .collect::>(); + // row + // }) + // .collect::>(); + // + // Ok(rows.into()) + todo!() +} 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 cbdb457577..42af2ef4c4 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -1,7 +1,7 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; use flowy_grid::services::field::{SelectOption, SingleSelectDescription}; -use flowy_grid_data_model::entities::FieldChangeset; +use flowy_grid_data_model::entities::{FieldChangeset, GridBlock, GridBlockChangeset}; #[tokio::test] async fn default_grid_test() { @@ -35,6 +35,23 @@ async fn grid_create_field() { GridEditorTest::new().await.run_scripts(scripts).await; } +#[tokio::test] +async fn grid_create_duplicate_field() { + let text_field = create_text_field(); + let scripts = vec![ + AssertFieldCount(2), + CreateField { + field: text_field.clone(), + }, + AssertFieldCount(3), + CreateField { + field: text_field.clone(), + }, + AssertFieldCount(3), + ]; + GridEditorTest::new().await.run_scripts(scripts).await; +} + #[tokio::test] async fn grid_update_field_with_empty_change() { let single_select_field = create_single_select_field(); @@ -98,3 +115,60 @@ async fn grid_update_field() { ]; GridEditorTest::new().await.run_scripts(scripts).await; } + +#[tokio::test] +async fn grid_delete_field() { + let text_field = create_text_field(); + let scripts = vec![ + CreateField { + field: text_field.clone(), + }, + AssertFieldCount(3), + DeleteField { field: text_field }, + AssertFieldCount(2), + ]; + GridEditorTest::new().await.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_create_block() { + let grid_block = GridBlock::new(); + let scripts = vec![ + AssertBlockCount(1), + CreateBlock { block: grid_block }, + AssertBlockCount(2), + ]; + GridEditorTest::new().await.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_update_block() { + let grid_block = GridBlock::new(); + let mut cloned_grid_block = grid_block.clone(); + let change = GridBlockChangeset { + block_id: grid_block.id.clone(), + start_row_index: Some(2), + row_count: Some(10), + }; + + cloned_grid_block.start_row_index = 2; + cloned_grid_block.row_count = 10; + + let scripts = vec![ + AssertBlockCount(1), + CreateBlock { block: grid_block }, + UpdateBlock { change }, + AssertBlockCount(2), + AssertBlockEqual { + block_index: 1, + block: cloned_grid_block, + }, + ]; + GridEditorTest::new().await.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_create_row() { + let scripts = vec![AssertRowCount(2), CreateRow, CreateRow, CreateRow, AssertRowCount(5)]; + GridEditorTest::new().await.run_scripts(scripts).await; +} diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 523e1d4e12..277cd6b4da 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 flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; -use flowy_grid_data_model::entities::{AnyData, Field, FieldChangeset, FieldType}; +use flowy_grid_data_model::entities::{AnyData, Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset}; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::event_builder::FolderEventBuilder; use flowy_test::helper::ViewTest; @@ -12,10 +12,17 @@ use tokio::time::sleep; pub enum EditorScript { CreateField { field: Field }, UpdateField { change: FieldChangeset }, + DeleteField { field: Field }, AssertFieldCount(usize), AssertFieldEqual { field_index: usize, field: Field }, - AssertGridMetaPad, + CreateBlock { block: GridBlock }, + UpdateBlock { change: GridBlockChangeset }, + AssertBlockCount(usize), + AssertBlockEqual { block_index: usize, block: GridBlock }, CreateRow, + AssertRowCount(usize), + // AssertRowEqual{ row_index: usize, row: RowMeta}, + AssertGridMetaPad, } pub struct GridEditorTest { @@ -53,6 +60,9 @@ impl GridEditorTest { EditorScript::UpdateField { change } => { self.editor.update_field(change).await.unwrap(); } + EditorScript::DeleteField { field } => { + self.editor.delete_field(&field.id).await.unwrap(); + } EditorScript::AssertFieldCount(count) => { assert_eq!(self.editor.get_fields(None).await.unwrap().len(), count); } @@ -61,13 +71,32 @@ impl GridEditorTest { let compared_field = repeated_fields[field_index].clone(); assert_eq!(compared_field, field); } + EditorScript::CreateBlock { block } => { + self.editor.create_block(block).await.unwrap(); + } + EditorScript::UpdateBlock { change } => { + self.editor.update_block(change).await.unwrap(); + } + EditorScript::AssertBlockCount(count) => { + assert_eq!(self.editor.get_blocks().await.unwrap().len(), count); + } + EditorScript::AssertBlockEqual { block_index, block } => { + let blocks = self.editor.get_blocks().await.unwrap(); + let compared_block = blocks[block_index].clone(); + assert_eq!(compared_block, block); + } + EditorScript::CreateRow => { + self.editor.create_row().await.unwrap(); + } + EditorScript::AssertRowCount(count) => { + assert_eq!(self.editor.get_rows(None).await.unwrap().len(), count); + } EditorScript::AssertGridMetaPad => { sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await; let mut grid_rev_manager = grid_manager.make_grid_rev_manager(&self.grid_id, pool.clone()).unwrap(); let grid_pad = grid_rev_manager.load::(None).await.unwrap(); println!("{}", grid_pad.delta_str()); } - EditorScript::CreateRow => {} } } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index 1252f0d842..b63c667cbd 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -69,6 +69,10 @@ impl GridBlockMetaPad { .collect::>()) } + pub fn number_of_rows(&self) -> i32 { + self.rows.len() as i32 + } + pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { let row_id = changeset.row_id.clone(); self.modify_row(&row_id, |row| { diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index 30cd8cd2e0..9ba6cc7ff5 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -31,7 +31,7 @@ impl GridBuilder { } pub fn add_empty_row(mut self) -> Self { - let row = RowMeta::new(&self.grid_block.id, vec![]); + let row = RowMeta::new(&self.grid_block.id); self.grid_block_meta.rows.push(row); self } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 12d1b14c5b..304919a310 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -36,8 +36,13 @@ impl GridMetaPad { pub fn create_field(&mut self, field: Field) -> CollaborateResult> { self.modify_grid(|grid| { - grid.fields.push(field); - Ok(Some(())) + if grid.fields.contains(&field) { + tracing::warn!("Duplicate grid field"); + Ok(None) + } else { + grid.fields.push(field); + Ok(Some(())) + } }) } @@ -51,7 +56,7 @@ impl GridMetaPad { }) } - pub fn get_fields(&self, field_orders: Option) -> CollaborateResult { + pub fn get_fields(&self, field_orders: Option) -> CollaborateResult> { match field_orders { None => Ok(self.grid_meta.fields.clone().into()), Some(field_orders) => { @@ -72,7 +77,7 @@ impl GridMetaPad { Some(field) => Some((*field).clone()), }) .collect::>(); - Ok(fields.into()) + Ok(fields) } } } @@ -122,8 +127,13 @@ impl GridMetaPad { pub fn create_block(&mut self, block: GridBlock) -> CollaborateResult> { self.modify_grid(|grid| { - grid.blocks.push(block); - Ok(Some(())) + if grid.blocks.iter().find(|b| b.id == block.id).is_some() { + tracing::warn!("Duplicate grid block"); + Ok(None) + } else { + grid.blocks.push(block); + Ok(Some(())) + } }) } @@ -141,6 +151,11 @@ impl GridMetaPad { is_changed = Some(()); } + if let Some(start_row_index) = change.start_row_index { + block.start_row_index = start_row_index; + is_changed = Some(()); + } + Ok(is_changed) }) } 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 00c3981d79..d2bf2173f3 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -45,11 +45,17 @@ impl std::ops::Deref for RepeatedFieldOrder { pub struct RowOrder { #[pb(index = 1)] pub row_id: String, + + #[pb(index = 2)] + pub block_id: String, } impl std::convert::From<&RowMeta> for RowOrder { fn from(row: &RowMeta) -> Self { - Self { row_id: row.id.clone() } + Self { + row_id: row.id.clone(), + block_id: row.block_id.clone(), + } } } @@ -111,12 +117,9 @@ impl std::convert::From> for RepeatedRow { #[derive(Debug, Default, ProtoBuf)] pub struct Cell { #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] pub field_id: String, - #[pb(index = 3)] + #[pb(index = 2)] pub content: String, } diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 8ef8df08e4..2813759448 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -18,7 +18,7 @@ pub struct GridMeta { pub blocks: Vec, } -#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] pub struct GridBlock { #[pb(index = 1)] pub id: String, @@ -45,6 +45,16 @@ pub struct GridBlockChangeset { pub row_count: Option, } +impl GridBlockChangeset { + pub fn from_row_count(block_id: &str, row_count: i32) -> Self { + Self { + block_id: block_id.to_string(), + start_row_index: None, + row_count: Some(row_count), + } + } +} + #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] pub struct GridBlockMeta { #[pb(index = 1)] @@ -225,7 +235,7 @@ impl ToString for AnyData { } } -#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] pub struct RowMeta { #[pb(index = 1)] pub id: String, @@ -244,16 +254,11 @@ pub struct RowMeta { } impl RowMeta { - pub fn new(block_id: &str, cells: Vec) -> Self { - let cell_by_field_id = cells - .into_iter() - .map(|cell| (cell.id.clone(), cell)) - .collect::>(); - + pub fn new(block_id: &str) -> Self { Self { id: uuid::Uuid::new_v4().to_string(), block_id: block_id.to_owned(), - cell_by_field_id, + cell_by_field_id: Default::default(), height: DEFAULT_ROW_HEIGHT, visibility: true, } @@ -275,20 +280,20 @@ pub struct RowMetaChangeset { pub cell_by_field_id: HashMap, } -#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)] pub struct CellMeta { #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub row_id: String, - - #[pb(index = 3)] pub field_id: String, - #[pb(index = 4)] - pub data: AnyData, - - #[pb(index = 5)] - pub height: i32, + #[pb(index = 2)] + pub data: String, +} + +impl CellMeta { + pub fn new(field_id: &str, data: String) -> Self { + Self { + field_id: field_id.to_string(), + data, + } + } } 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 c4f57568e9..e7a7561068 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 @@ -609,6 +609,7 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedFieldOrder { pub struct RowOrder { // message fields pub row_id: ::std::string::String, + pub block_id: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -650,6 +651,32 @@ impl RowOrder { pub fn take_row_id(&mut self) -> ::std::string::String { ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) } + + // string block_id = 2; + + + pub fn get_block_id(&self) -> &str { + &self.block_id + } + pub fn clear_block_id(&mut self) { + self.block_id.clear(); + } + + // Param is passed by value, moved + pub fn set_block_id(&mut self, v: ::std::string::String) { + self.block_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id + } + + // Take field + pub fn take_block_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) + } } impl ::protobuf::Message for RowOrder { @@ -664,6 +691,9 @@ impl ::protobuf::Message for RowOrder { 1 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -679,6 +709,9 @@ impl ::protobuf::Message for RowOrder { if !self.row_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.row_id); } + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.block_id); + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -688,6 +721,9 @@ impl ::protobuf::Message for RowOrder { if !self.row_id.is_empty() { os.write_string(1, &self.row_id)?; } + if !self.block_id.is_empty() { + os.write_string(2, &self.block_id)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -731,6 +767,11 @@ impl ::protobuf::Message for RowOrder { |m: &RowOrder| { &m.row_id }, |m: &mut RowOrder| { &mut m.row_id }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "block_id", + |m: &RowOrder| { &m.block_id }, + |m: &mut RowOrder| { &mut m.block_id }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "RowOrder", fields, @@ -748,6 +789,7 @@ impl ::protobuf::Message for RowOrder { impl ::protobuf::Clear for RowOrder { fn clear(&mut self) { self.row_id.clear(); + self.block_id.clear(); self.unknown_fields.clear(); } } @@ -1330,7 +1372,6 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedRow { #[derive(PartialEq,Clone,Default)] pub struct Cell { // message fields - pub id: ::std::string::String, pub field_id: ::std::string::String, pub content: ::std::string::String, // special fields @@ -1349,33 +1390,7 @@ impl Cell { ::std::default::Default::default() } - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string field_id = 2; + // string field_id = 1; pub fn get_field_id(&self) -> &str { @@ -1401,7 +1416,7 @@ impl Cell { ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) } - // string content = 3; + // string content = 2; pub fn get_content(&self) -> &str { @@ -1438,12 +1453,9 @@ impl ::protobuf::Message for Cell { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; }, - 3 => { + 2 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.content)?; }, _ => { @@ -1458,14 +1470,11 @@ impl ::protobuf::Message for Cell { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } if !self.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.field_id); + my_size += ::protobuf::rt::string_size(1, &self.field_id); } if !self.content.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.content); + my_size += ::protobuf::rt::string_size(2, &self.content); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -1473,14 +1482,11 @@ impl ::protobuf::Message for Cell { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } if !self.field_id.is_empty() { - os.write_string(2, &self.field_id)?; + os.write_string(1, &self.field_id)?; } if !self.content.is_empty() { - os.write_string(3, &self.content)?; + os.write_string(2, &self.content)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -1520,11 +1526,6 @@ impl ::protobuf::Message for Cell { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &Cell| { &m.id }, - |m: &mut Cell| { &mut m.id }, - )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "field_id", |m: &Cell| { &m.field_id }, @@ -1551,7 +1552,6 @@ impl ::protobuf::Message for Cell { impl ::protobuf::Clear for Cell { fn clear(&mut self) { - self.id.clear(); self.field_id.clear(); self.content.clear(); self.unknown_fields.clear(); @@ -2326,17 +2326,17 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ders\x12(\n\nrow_orders\x18\x03\x20\x03(\x0b2\t.RowOrderR\trowOrders\"'\ \n\nFieldOrder\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"7\n\ \x12RepeatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOr\ - derR\x05items\"!\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\ - \x05rowId\"3\n\x10RepeatedRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\ - \x0b2\t.RowOrderR\x05items\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\ - \x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.\ - Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\ - \x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\ - \x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.Cel\ - lR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\ - \x03(\x0b2\x04.RowR\x05items\"K\n\x04Cell\x12\x0e\n\x02id\x18\x01\x20\ - \x01(\tR\x02id\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12\ - \x18\n\x07content\x18\x03\x20\x01(\tR\x07content\"'\n\x11CreateGridPaylo\ + derR\x05items\"<\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\ + \x05rowId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\"3\n\x10R\ + epeatedRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05\ + items\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12@\ + \n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\ + \rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\ + \n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\ + \x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\ + \x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05ite\ + ms\";\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\ + \x18\n\x07content\x18\x02\x20\x01(\tR\x07content\"'\n\x11CreateGridPaylo\ ad\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\ \x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"d\n\x11QueryFieldPayload\ \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orde\ diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index cd222c2868..a9fccf6d54 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -2758,11 +2758,8 @@ impl ::protobuf::reflect::ProtobufValue for RowMetaChangeset { #[derive(PartialEq,Clone,Default)] pub struct CellMeta { // message fields - pub id: ::std::string::String, - pub row_id: ::std::string::String, pub field_id: ::std::string::String, - pub data: ::protobuf::SingularPtrField, - pub height: i32, + pub data: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -2779,59 +2776,7 @@ impl CellMeta { ::std::default::Default::default() } - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string row_id = 2; - - - pub fn get_row_id(&self) -> &str { - &self.row_id - } - pub fn clear_row_id(&mut self) { - self.row_id.clear(); - } - - // Param is passed by value, moved - pub fn set_row_id(&mut self, v: ::std::string::String) { - self.row_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_row_id(&mut self) -> &mut ::std::string::String { - &mut self.row_id - } - - // Take field - pub fn take_row_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) - } - - // string field_id = 3; + // string field_id = 1; pub fn get_field_id(&self) -> &str { @@ -2857,62 +2802,35 @@ impl CellMeta { ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) } - // .AnyData data = 4; + // string data = 2; - pub fn get_data(&self) -> &AnyData { - self.data.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_data(&self) -> &str { + &self.data } pub fn clear_data(&mut self) { self.data.clear(); } - pub fn has_data(&self) -> bool { - self.data.is_some() - } - // Param is passed by value, moved - pub fn set_data(&mut self, v: AnyData) { - self.data = ::protobuf::SingularPtrField::some(v); + pub fn set_data(&mut self, v: ::std::string::String) { + 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 AnyData { - if self.data.is_none() { - self.data.set_default(); - } - self.data.as_mut().unwrap() + pub fn mut_data(&mut self) -> &mut ::std::string::String { + &mut self.data } // Take field - pub fn take_data(&mut self) -> AnyData { - self.data.take().unwrap_or_else(|| AnyData::new()) - } - - // int32 height = 5; - - - pub fn get_height(&self) -> i32 { - self.height - } - pub fn clear_height(&mut self) { - self.height = 0; - } - - // Param is passed by value, moved - pub fn set_height(&mut self, v: i32) { - self.height = v; + pub fn take_data(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.data, ::std::string::String::new()) } } impl ::protobuf::Message for CellMeta { fn is_initialized(&self) -> bool { - for v in &self.data { - if !v.is_initialized() { - return false; - } - }; true } @@ -2921,23 +2839,10 @@ impl ::protobuf::Message for CellMeta { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; - }, - 3 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; }, - 4 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.data)?; - }, - 5 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.height = tmp; + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -2951,21 +2856,11 @@ impl ::protobuf::Message for CellMeta { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.row_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.row_id); - } if !self.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.field_id); + my_size += ::protobuf::rt::string_size(1, &self.field_id); } - if let Some(ref v) = self.data.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - if self.height != 0 { - my_size += ::protobuf::rt::value_size(5, self.height, ::protobuf::wire_format::WireTypeVarint); + if !self.data.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.data); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -2973,22 +2868,11 @@ impl ::protobuf::Message for CellMeta { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.row_id.is_empty() { - os.write_string(2, &self.row_id)?; - } if !self.field_id.is_empty() { - os.write_string(3, &self.field_id)?; + os.write_string(1, &self.field_id)?; } - if let Some(ref v) = self.data.as_ref() { - os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - if self.height != 0 { - os.write_int32(5, self.height)?; + if !self.data.is_empty() { + os.write_string(2, &self.data)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -3028,31 +2912,16 @@ impl ::protobuf::Message for CellMeta { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &CellMeta| { &m.id }, - |m: &mut CellMeta| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_id", - |m: &CellMeta| { &m.row_id }, - |m: &mut CellMeta| { &mut m.row_id }, - )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "field_id", |m: &CellMeta| { &m.field_id }, |m: &mut CellMeta| { &mut m.field_id }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "data", |m: &CellMeta| { &m.data }, |m: &mut CellMeta| { &mut m.data }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "height", - |m: &CellMeta| { &m.height }, - |m: &mut CellMeta| { &mut m.height }, - )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "CellMeta", fields, @@ -3069,11 +2938,8 @@ impl ::protobuf::Message for CellMeta { impl ::protobuf::Clear for CellMeta { fn clear(&mut self) { - self.id.clear(); - self.row_id.clear(); self.field_id.clear(); self.data.clear(); - self.height = 0; self.unknown_fields.clear(); } } @@ -3191,14 +3057,12 @@ static file_descriptor_proto_data: &'static [u8] = b"\ field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rce\ llByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\ \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\ - value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"\x82\ - \x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\ - \x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\ - \x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\x08.AnyD\ - ataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06height*d\n\tFi\ - eldType\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\x0bMult\ - iSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ + value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"9\n\ + \x08CellMeta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\ + \x12\n\x04data\x18\x02\x20\x01(\tR\x04data*d\n\tFieldType\x12\x0c\n\x08R\ + ichText\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\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index b8577c6e3c..4e395edc92 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 @@ -13,6 +13,7 @@ message RepeatedFieldOrder { } message RowOrder { string row_id = 1; + string block_id = 2; } message RepeatedRowOrder { repeated RowOrder items = 1; @@ -26,9 +27,8 @@ message RepeatedRow { repeated Row items = 1; } message Cell { - string id = 1; - string field_id = 2; - string content = 3; + string field_id = 1; + string content = 2; } message CreateGridPayload { string name = 1; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 503284f7b5..190c400f04 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -55,11 +55,8 @@ message RowMetaChangeset { map cell_by_field_id = 4; } message CellMeta { - string id = 1; - string row_id = 2; - string field_id = 3; - AnyData data = 4; - int32 height = 5; + string field_id = 1; + string data = 2; } enum FieldType { RichText = 0; From d101509b325d1abf9da76e930825c56a25bcc64a Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 13 Mar 2022 23:16:52 +0800 Subject: [PATCH 17/28] chore: add row test --- .../rust-lib/flowy-grid/src/event_handler.rs | 6 +- .../src/services/field/field_builder.rs | 2 +- .../src/services/field/type_options.rs | 79 ++++++------- .../flowy-grid/src/services/grid_editor.rs | 35 +++--- .../src/services/grid_meta_editor.rs | 67 ++++++----- .../src/services/row/cell_stringify.rs | 14 +-- .../flowy-grid/src/services/row/mod.rs | 2 +- .../flowy-grid/src/services/row/row_loader.rs | 109 ++++++++++-------- frontend/rust-lib/flowy-grid/src/util.rs | 2 +- .../flowy-grid/tests/grid/grid_test.rs | 2 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 6 +- .../src/client_grid/block_pad.rs | 6 +- .../src/client_grid/grid_builder.rs | 2 +- .../src/client_grid/grid_pad.rs | 6 +- .../src/entities/grid.rs | 9 ++ .../src/entities/meta.rs | 8 +- 16 files changed, 191 insertions(+), 164 deletions(-) diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 0861f2aaa1..22dff6e191 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -24,7 +24,7 @@ pub(crate) async fn get_rows_handler( ) -> DataResult { let payload: QueryRowPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_row: RepeatedRow = editor.get_rows(Some(payload.row_orders)).await?.into(); + let repeated_row: RepeatedRow = editor.get_rows(payload.row_orders).await?.into(); data_result(repeated_row) } @@ -50,10 +50,10 @@ pub(crate) async fn create_row_handler( Ok(()) } -#[tracing::instrument(level = "debug", skip(data, manager), err)] +#[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn update_cell_handler( data: Data, - manager: AppData>, + _manager: AppData>, ) -> Result<(), FlowyError> { let _cell: Cell = data.into_inner(); // let editor = manager.get_grid_editor(id.as_ref())?; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index 86dab02b67..8b75389ce4 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -2,7 +2,7 @@ use crate::services::field::{ CheckboxDescription, DateDescription, DateFormat, MoneySymbol, MultiSelectDescription, NumberDescription, RichTextDescription, SelectOption, SingleSelectDescription, TimeFormat, }; -use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; +use flowy_grid_data_model::entities::{Field, FieldType}; pub struct FieldBuilder { field: Field, diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs index b192a1e118..080e3aaa60 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs @@ -2,12 +2,12 @@ use crate::impl_from_and_to_type_option; use crate::services::row::StringifyCellData; use crate::services::util::*; -use bytes::Bytes; + use chrono::format::strftime::StrftimeItems; use chrono::NaiveDateTime; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; +use flowy_grid_data_model::entities::{Field, FieldType}; use rust_decimal::Decimal; use rusty_money::{ iso::{Currency, CNY, EUR, USD}, @@ -25,12 +25,12 @@ pub struct RichTextDescription { impl_from_and_to_type_option!(RichTextDescription, FieldType::RichText); impl StringifyCellData for RichTextDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - data.to_string() + fn str_from_cell_data(&self, data: String) -> String { + data } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(AnyData::from_str(self.field_type(), s)) + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(s.to_owned()) } } @@ -43,16 +43,16 @@ pub struct CheckboxDescription { impl_from_and_to_type_option!(CheckboxDescription, FieldType::Checkbox); impl StringifyCellData for CheckboxDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - data.to_string() + fn str_from_cell_data(&self, data: String) -> String { + data } - fn str_to_cell_data(&self, s: &str) -> Result { + fn str_to_cell_data(&self, s: &str) -> Result { let s = match string_to_bool(s) { true => "1", false => "0", }; - Ok(AnyData::from_str(self.field_type(), s)) + Ok(s.to_owned()) } } @@ -89,30 +89,24 @@ impl DateDescription { } impl StringifyCellData for DateDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - match String::from_utf8(data.value) { - Ok(s) => match s.parse::() { - Ok(timestamp) => { - let native = NaiveDateTime::from_timestamp(timestamp, 0); - self.today_from_native(native) - } - Err(e) => { - tracing::debug!("DateDescription format {} fail. error: {:?}", s, e); - String::new() - } - }, + fn str_from_cell_data(&self, data: String) -> String { + match data.parse::() { + Ok(timestamp) => { + let native = NaiveDateTime::from_timestamp(timestamp, 0); + self.today_from_native(native) + } Err(e) => { - tracing::error!("DateDescription stringify any_data failed. {:?}", e); + tracing::debug!("DateDescription format {} fail. error: {:?}", data, e); String::new() } } } - fn str_to_cell_data(&self, s: &str) -> Result { + fn str_to_cell_data(&self, s: &str) -> Result { let timestamp = s .parse::() .map_err(|e| FlowyError::internal().context(format!("Parse {} to i64 failed: {}", s, e)))?; - Ok(AnyData::from_str(self.field_type(), &format!("{}", timestamp))) + Ok(format!("{}", timestamp)) } } @@ -210,12 +204,12 @@ pub struct SingleSelectDescription { impl_from_and_to_type_option!(SingleSelectDescription, FieldType::SingleSelect); impl StringifyCellData for SingleSelectDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - data.to_string() + fn str_from_cell_data(&self, data: String) -> String { + data } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(AnyData::from_str(self.field_type(), s)) + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(s.to_owned()) } } @@ -230,12 +224,12 @@ pub struct MultiSelectDescription { } impl_from_and_to_type_option!(MultiSelectDescription, FieldType::MultiSelect); impl StringifyCellData for MultiSelectDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - data.to_string() + fn str_from_cell_data(&self, data: String) -> String { + data } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(AnyData::from_str(self.field_type(), s)) + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(s.to_owned()) } } @@ -322,24 +316,17 @@ impl NumberDescription { } impl StringifyCellData for NumberDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - match String::from_utf8(data.value) { - Ok(s) => match self.money_from_str(&s) { - Some(money_str) => money_str, - None => String::default(), - }, - Err(e) => { - tracing::error!("NumberDescription stringify any_data failed. {:?}", e); - String::new() - } + fn str_from_cell_data(&self, data: String) -> String { + match self.money_from_str(&data) { + Some(money_str) => money_str, + None => String::default(), } } - fn str_to_cell_data(&self, s: &str) -> Result { + fn str_to_cell_data(&self, s: &str) -> Result { let strip_symbol_money = strip_money_symbol(s); let decimal = Decimal::from_str(&strip_symbol_money).map_err(|err| FlowyError::internal().context(err))?; - let money_str = decimal.to_string(); - Ok(AnyData::from_str(self.field_type(), &money_str)) + Ok(decimal.to_string()) } } 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 4b7250079e..63defcf76b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,7 +1,7 @@ use crate::manager::GridUser; use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; -use crate::services::grid_meta_editor::{ClientGridBlockMetaEditor, GridBlockMetaEditorManager}; +use crate::services::grid_meta_editor::GridBlockMetaEditorManager; use bytes::Bytes; use dashmap::DashMap; use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; @@ -9,13 +9,10 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Field, FieldChangeset, Grid, GridBlock, GridBlockChangeset, RepeatedField, RepeatedFieldOrder, RepeatedRow, - RepeatedRowOrder, Row, -}; -use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; -use flowy_sync::{ - RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, + Field, FieldChangeset, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, RepeatedRowOrder, Row, }; + +use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; use std::sync::Arc; @@ -83,23 +80,29 @@ impl ClientGridEditor { pub async fn create_row(&self) -> FlowyResult<()> { let fields = self.grid_meta_pad.read().await.get_fields(None)?; - match self.grid_meta_pad.read().await.get_blocks().last() { + let grid_block = match self.grid_meta_pad.read().await.get_blocks().last() { None => Err(FlowyError::internal().context("There is no grid block in this grid")), - Some(grid_block) => { - let row_count = self.block_meta_manager.create_row(fields, grid_block).await?; - let change = GridBlockChangeset::from_row_count(&grid_block.id, row_count); - let _ = self.update_block(change).await?; - Ok(()) - } - } + Some(grid_block) => Ok(grid_block.clone()), + }?; + + let row_count = self.block_meta_manager.create_row(fields, &grid_block).await?; + let change = GridBlockChangeset::from_row_count(&grid_block.id, row_count); + let _ = self.update_block(change).await?; + Ok(()) } - pub async fn get_rows(&self, row_orders: Option) -> FlowyResult> { + pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult> { let fields = self.grid_meta_pad.read().await.get_fields(None)?; let rows = self.block_meta_manager.get_rows(fields, row_orders).await?; Ok(rows) } + pub async fn get_all_rows(&self) -> FlowyResult> { + let fields = self.grid_meta_pad.read().await.get_fields(None)?; + let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); + self.block_meta_manager.get_all_rows(grid_blocks, fields).await + } + pub async fn delete_rows(&self, row_orders: Option) -> FlowyResult<()> { let row_counts = self.block_meta_manager.delete_rows(row_orders).await?; for (block_id, row_count) in row_counts { diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs index 5358b4cde5..211af6d340 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs @@ -1,22 +1,20 @@ use crate::manager::GridUser; -use crate::services::row::{make_row_ids_per_block, make_rows, sort_rows, RowBuilder}; +use crate::services::row::{make_row_by_row_id, make_row_ids_per_block, make_rows, RowBuilder}; use bytes::Bytes; -use dashmap::mapref::one::Ref; + use dashmap::DashMap; use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{ - Field, GridBlock, RepeatedRow, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, -}; +use flowy_grid_data_model::entities::{Field, GridBlock, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset}; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_sync::{ RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, }; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; -use lib_sqlite::ConnectionPool; + use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; @@ -52,32 +50,34 @@ impl GridBlockMetaEditorManager { editor.create_row(row).await } - pub(crate) async fn delete_rows(&self, row_orders: Option) -> FlowyResult> { + pub(crate) async fn delete_rows(&self, _row_orders: Option) -> FlowyResult> { Ok(vec![("".to_owned(), 2)]) } - pub(crate) async fn get_rows( - &self, - fields: Vec, - row_orders: Option, - ) -> FlowyResult> { - match row_orders { - None => { - let rows = vec![]; - Ok(rows) - } - Some(row_orders) => { - let row_ids_per_blocks = make_row_ids_per_block(&row_orders); - let mut rows = vec![]; - for row_ids_per_block in row_ids_per_blocks { - let editor = self.get_editor(&row_ids_per_block.block_id).await?; - let row_metas = editor.get_rows(row_ids_per_block.row_ids).await?; - rows.extend(make_rows(&fields, row_metas)); - } - sort_rows(&mut rows, row_orders); - Ok(rows) - } + pub(crate) async fn get_all_rows(&self, grid_blocks: Vec, fields: Vec) -> FlowyResult> { + let mut rows = vec![]; + for grid_block in grid_blocks { + let editor = self.get_editor(&grid_block.id).await?; + let row_metas = editor.get_rows(None).await?; + rows.extend(make_rows(&fields, row_metas)); } + Ok(rows) + } + + pub(crate) async fn get_rows(&self, fields: Vec, row_orders: RepeatedRowOrder) -> FlowyResult> { + let row_ids_per_blocks = make_row_ids_per_block(&row_orders); + let mut row_map: HashMap = HashMap::new(); + for row_ids_per_block in row_ids_per_blocks { + let editor = self.get_editor(&row_ids_per_block.block_id).await?; + let row_metas = editor.get_rows(Some(row_ids_per_block.row_ids)).await?; + row_map.extend(make_row_by_row_id(&fields, row_metas)); + } + + let rows = row_orders + .iter() + .flat_map(|row_order| row_map.remove(&row_order.row_id)) + .collect::>(); + Ok(rows) } } @@ -158,9 +158,14 @@ impl ClientGridBlockMetaEditor { Ok(()) } - pub async fn get_rows(&self, row_ids: Vec) -> FlowyResult> { - let rows = self.meta_pad.read().await.get_rows(row_ids)?; - Ok(rows) + pub async fn get_rows(&self, row_ids: Option>) -> FlowyResult> { + match row_ids { + None => Ok(self.meta_pad.read().await.all_rows()), + Some(row_ids) => { + let rows = self.meta_pad.read().await.get_rows(row_ids)?; + Ok(rows) + } + } } async fn modify(&self, f: F) -> FlowyResult<()> diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs index a75506e339..cd68038b9c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs @@ -1,15 +1,15 @@ use crate::services::field::*; -use crate::services::util::*; + use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; +use flowy_grid_data_model::entities::{Field, FieldType}; pub trait StringifyCellData { - fn str_from_cell_data(&self, data: AnyData) -> String; - fn str_to_cell_data(&self, s: &str) -> Result; + fn str_from_cell_data(&self, data: String) -> String; + fn str_to_cell_data(&self, s: &str) -> Result; } #[allow(dead_code)] -pub fn stringify_serialize(field: &Field, s: &str) -> Result { +pub fn stringify_serialize(field: &Field, s: &str) -> Result { match field.field_type { FieldType::RichText => RichTextDescription::from(field).str_to_cell_data(s), FieldType::Number => NumberDescription::from(field).str_to_cell_data(s), @@ -20,8 +20,8 @@ pub fn stringify_serialize(field: &Field, s: &str) -> Result Result { - let _ = check_type_id(&data, field)?; +pub(crate) fn stringify_deserialize(data: String, field: &Field) -> Result { + // let _ = check_type_id(&data, field)?; let s = match field.field_type { FieldType::RichText => RichTextDescription::from(field).str_from_cell_data(data), FieldType::Number => NumberDescription::from(field).str_from_cell_data(data), diff --git a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs index baac627e00..993e3401e3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs @@ -4,4 +4,4 @@ mod row_loader; pub use cell_stringify::*; pub use row_builder::*; -pub use row_loader::*; +pub(crate) use row_loader::*; 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 f9092a5d89..705871ad93 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 @@ -1,4 +1,6 @@ -use flowy_grid_data_model::entities::{Field, RepeatedRowOrder, Row, RowMeta}; +use crate::services::row::stringify_deserialize; +use flowy_grid_data_model::entities::{Cell, CellMeta, Field, RepeatedRowOrder, Row, RowMeta}; +use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; pub(crate) struct RowIdsPerBlock { @@ -19,50 +21,67 @@ pub(crate) fn make_row_ids_per_block(row_orders: &RepeatedRowOrder) -> Vec>() } -pub(crate) fn sort_rows(rows: &mut Vec, row_orders: RepeatedRowOrder) { - todo!() +pub(crate) fn make_rows(fields: &Vec, row_metas: Vec) -> Vec { + let field_map = fields + .iter() + .map(|field| (&field.id, field)) + .collect::>(); + + let make_row = |row_meta: RowMeta| { + let cell_by_field_id = row_meta + .cell_by_field_id + .into_par_iter() + .flat_map(|(field_id, raw_cell)| make_cell(&field_map, field_id, raw_cell)) + .collect::>(); + + Row { + id: row_meta.id.clone(), + cell_by_field_id, + height: row_meta.height, + } + }; + + row_metas.into_iter().map(make_row).collect::>() } -pub(crate) fn make_rows(fields: &Vec, rows: Vec) -> Vec { - // let make_cell = |field_id: String, raw_cell: CellMeta| { - // let some_field = self.field_map.get(&field_id); - // if some_field.is_none() { - // tracing::error!("Can't find the field with {}", field_id); - // return None; - // } - // self.cell_map.insert(raw_cell.id.clone(), raw_cell.clone()); - // - // let field = some_field.unwrap(); - // match stringify_deserialize(raw_cell.data, field.value()) { - // Ok(content) => { - // let cell = Cell { - // id: raw_cell.id, - // field_id: field_id.clone(), - // content, - // }; - // Some((field_id, cell)) - // } - // Err(_) => None, - // } - // }; - // - // let rows = row_metas - // .into_par_iter() - // .map(|row_meta| { - // let mut row = Row { - // id: row_meta.id.clone(), - // cell_by_field_id: Default::default(), - // height: row_meta.height, - // }; - // row.cell_by_field_id = row_meta - // .cell_by_field_id - // .into_par_iter() - // .flat_map(|(field_id, raw_cell)| make_cell(field_id, raw_cell)) - // .collect::>(); - // row - // }) - // .collect::>(); - // - // Ok(rows.into()) - todo!() +#[inline(always)] +fn make_cell(field_map: &HashMap<&String, &Field>, field_id: String, raw_cell: CellMeta) -> Option<(String, Cell)> { + let field = field_map.get(&field_id)?; + match stringify_deserialize(raw_cell.data, field) { + Ok(content) => { + let cell = Cell::new(&field_id, content); + Some((field_id, cell)) + } + Err(e) => { + tracing::error!("{}", e); + None + } + } +} + +pub(crate) fn make_row_by_row_id(fields: &Vec, row_metas: Vec) -> HashMap { + let field_map = fields + .iter() + .map(|field| (&field.id, field)) + .collect::>(); + + let make_row = |row_meta: RowMeta| { + let cell_by_field_id = row_meta + .cell_by_field_id + .into_par_iter() + .flat_map(|(field_id, raw_cell)| make_cell(&field_map, field_id, raw_cell)) + .collect::>(); + + let row = Row { + id: row_meta.id.clone(), + cell_by_field_id, + height: row_meta.height, + }; + (row.id.clone(), row) + }; + + row_metas + .into_par_iter() + .map(make_row) + .collect::>() } diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index 8cf876a052..ef6060837e 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -1,6 +1,6 @@ use crate::services::field::*; use flowy_collaboration::client_grid::{BuildGridInfo, GridBuilder}; -use flowy_grid_data_model::entities::{Field, FieldType}; +use flowy_grid_data_model::entities::FieldType; pub fn make_default_grid(grid_id: &str) -> BuildGridInfo { let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::new()) 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 42af2ef4c4..410e7638a5 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -169,6 +169,6 @@ async fn grid_update_block() { #[tokio::test] async fn grid_create_row() { - let scripts = vec![AssertRowCount(2), CreateRow, CreateRow, CreateRow, AssertRowCount(5)]; + let scripts = vec![AssertRowCount(3), CreateRow, CreateRow, AssertRowCount(5)]; GridEditorTest::new().await.run_scripts(scripts).await; } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 277cd6b4da..278981dab3 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,8 +1,8 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; -use flowy_grid_data_model::entities::{AnyData, Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset}; +use flowy_grid_data_model::entities::{Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset}; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; -use flowy_test::event_builder::FolderEventBuilder; + use flowy_test::helper::ViewTest; use flowy_test::FlowySDKTest; use std::sync::Arc; @@ -89,7 +89,7 @@ impl GridEditorTest { self.editor.create_row().await.unwrap(); } EditorScript::AssertRowCount(count) => { - assert_eq!(self.editor.get_rows(None).await.unwrap().len(), count); + assert_eq!(self.editor.get_all_rows().await.unwrap().len(), count); } EditorScript::AssertGridMetaPad => { sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await; diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index b63c667cbd..790f9f3cfa 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -1,5 +1,5 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; -use crate::errors::{internal_error, CollaborateError, CollaborateResult}; +use crate::errors::{CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use flowy_grid_data_model::entities::{GridBlockMeta, RowMeta, RowMetaChangeset}; use lib_infra::uuid; @@ -69,6 +69,10 @@ impl GridBlockMetaPad { .collect::>()) } + pub fn all_rows(&self) -> Vec { + self.rows.iter().map(|row| (**row).clone()).collect::>() + } + pub fn number_of_rows(&self) -> i32 { self.rows.len() as i32 } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index 9ba6cc7ff5..b34f55b39b 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -1,6 +1,6 @@ use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBlockMetaDelta, GridMetaDelta}; use crate::errors::{CollaborateError, CollaborateResult}; -use flowy_grid_data_model::entities::{Field, FieldType, GridBlock, GridBlockMeta, GridMeta, RowMeta}; +use flowy_grid_data_model::entities::{Field, GridBlock, GridBlockMeta, GridMeta, RowMeta}; pub struct GridBuilder { grid_id: String, diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 304919a310..89d2145e17 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -2,7 +2,7 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use flowy_grid_data_model::entities::{ - Field, FieldChangeset, GridBlock, GridBlockChangeset, GridMeta, RepeatedField, RepeatedFieldOrder, + Field, FieldChangeset, GridBlock, GridBlockChangeset, GridMeta, RepeatedFieldOrder, }; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; @@ -58,7 +58,7 @@ impl GridMetaPad { pub fn get_fields(&self, field_orders: Option) -> CollaborateResult> { match field_orders { - None => Ok(self.grid_meta.fields.clone().into()), + None => Ok(self.grid_meta.fields.clone()), Some(field_orders) => { let field_by_field_id = self .grid_meta @@ -127,7 +127,7 @@ impl GridMetaPad { pub fn create_block(&mut self, block: GridBlock) -> CollaborateResult> { self.modify_grid(|grid| { - if grid.blocks.iter().find(|b| b.id == block.id).is_some() { + if grid.blocks.iter().any(|b| b.id == block.id) { tracing::warn!("Duplicate grid block"); Ok(None) } else { 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 d2bf2173f3..ef84bfe104 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -123,6 +123,15 @@ pub struct Cell { pub content: String, } +impl Cell { + pub fn new(field_id: &str, content: String) -> Self { + Self { + field_id: field_id.to_owned(), + content, + } + } +} + #[derive(ProtoBuf, Default)] pub struct CreateGridPayload { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 2813759448..dee0a2b21b 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -175,13 +175,13 @@ impl std::default::Default for FieldType { impl AsRef for FieldType { fn as_ref(&self) -> &FieldType { - &self + self } } -impl Into for &FieldType { - fn into(self) -> FieldType { - self.clone() +impl From<&FieldType> for FieldType { + fn from(field: &FieldType) -> Self { + field.clone() } } From 196d254278f76539af0c8f053defe0e0505a2f02 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 14 Mar 2022 17:24:25 +0800 Subject: [PATCH 18/28] chore: add row test --- frontend/app_flowy/lib/plugin/plugin.dart | 2 +- .../presentation/plugins/doc/document.dart | 2 +- .../flowy-grid-data-model/meta.pb.dart | 88 + .../flowy-grid-data-model/meta.pbjson.dart | 15 + .../flowy-grid/checkbox_description.pb.dart | 58 + .../checkbox_description.pbenum.dart | 7 + .../checkbox_description.pbjson.dart | 20 + .../checkbox_description.pbserver.dart | 9 + .../flowy-grid/date_description.pb.dart | 76 + .../flowy-grid/date_description.pbenum.dart | 45 + .../flowy-grid/date_description.pbjson.dart | 45 + .../flowy-grid/date_description.pbserver.dart | 9 + .../flowy-grid/number_description.pb.dart | 118 ++ .../flowy-grid/number_description.pbenum.dart | 28 + .../flowy-grid/number_description.pbjson.dart | 36 + .../number_description.pbserver.dart | 9 + .../lib/protobuf/flowy-grid/protobuf.dart | 6 +- .../flowy-grid/selection_description.pb.dart | 196 ++ .../selection_description.pbenum.dart | 7 + .../selection_description.pbjson.dart | 44 + .../selection_description.pbserver.dart | 9 + .../flowy-grid/text_description.pb.dart | 58 + .../flowy-grid/text_description.pbenum.dart | 7 + .../flowy-grid/text_description.pbjson.dart | 20 + .../flowy-grid/text_description.pbserver.dart | 9 + frontend/rust-lib/flowy-grid/Flowy.toml | 2 +- .../rust-lib/flowy-grid/src/event_handler.rs | 2 +- .../protobuf/model/checkbox_description.rs | 193 ++ .../src/protobuf/model/date_description.rs | 330 ++++ .../flowy-grid/src/protobuf/model/mod.rs | 16 +- .../src/protobuf/model/number_description.rs | 401 ++++ .../protobuf/model/selection_description.rs | 692 +++++++ .../src/protobuf/model/text_description.rs | 200 ++ .../src/protobuf/model/type_options.rs | 1656 ----------------- .../protobuf/proto/checkbox_description.proto | 5 + .../src/protobuf/proto/date_description.proto | 16 + .../protobuf/proto/number_description.proto | 14 + .../proto/selection_description.proto | 15 + .../src/protobuf/proto/text_description.proto | 5 + .../src/protobuf/proto/type_options.proto | 47 - .../src/services/cell/builder/mod.rs | 137 ++ .../cell/description/checkbox_description.rs | 40 + .../cell/description/date_description.rs | 145 ++ .../src/services/cell/description/mod.rs | 11 + .../cell/description/number_description.rs | 150 ++ .../cell/description/selection_description.rs | 70 + .../cell/description/text_description.rs | 24 + .../flowy-grid/src/services/cell/mod.rs | 5 + .../src/services/field/field_builder.rs | 158 -- .../flowy-grid/src/services/field/mod.rs | 2 - .../src/services/field/type_options.rs | 390 ---- .../flowy-grid/src/services/grid_editor.rs | 129 +- .../src/services/grid_meta_editor.rs | 136 +- .../rust-lib/flowy-grid/src/services/mod.rs | 1 + .../src/services/row/cell_stringify.rs | 3 +- .../src/services/row/row_builder.rs | 58 +- .../flowy-grid/src/services/row/row_loader.rs | 8 +- .../rust-lib/flowy-grid/src/services/util.rs | 27 +- frontend/rust-lib/flowy-grid/src/util.rs | 5 +- .../flowy-grid/tests/grid/grid_test.rs | 109 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 128 +- .../src/client_grid/grid_builder.rs | 1 + .../src/client_grid/grid_pad.rs | 26 +- .../src/entities/meta.rs | 33 + .../src/protobuf/model/meta.rs | 294 ++- .../src/protobuf/proto/meta.proto | 5 + 66 files changed, 4187 insertions(+), 2425 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbserver.dart create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/checkbox_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/date_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/selection_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/text_description.rs delete mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/type_options.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/checkbox_description.proto create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/date_description.proto create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_description.proto create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/text_description.proto delete mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/type_options.proto create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/description/mod.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/mod.rs delete mode 100644 frontend/rust-lib/flowy-grid/src/services/field/type_options.rs diff --git a/frontend/app_flowy/lib/plugin/plugin.dart b/frontend/app_flowy/lib/plugin/plugin.dart index 58b428cb94..607ebaab53 100644 --- a/frontend/app_flowy/lib/plugin/plugin.dart +++ b/frontend/app_flowy/lib/plugin/plugin.dart @@ -52,7 +52,7 @@ abstract class PluginBuilder { PluginType get pluginType; - ViewDataType get dataType => ViewDataType.Block; + ViewDataType get dataType => ViewDataType.TextBlock; } abstract class PluginConfig { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart index 249d47011b..048f417de0 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart @@ -50,7 +50,7 @@ class DocumentPluginBuilder extends PluginBuilder { PluginType get pluginType => DefaultPlugin.quill.type(); @override - ViewDataType get dataType => ViewDataType.Block; + ViewDataType get dataType => ViewDataType.TextBlock; } class DocumentPlugin implements Plugin { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 25104afa46..12dbec7975 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -956,3 +956,91 @@ class CellMeta extends $pb.GeneratedMessage { void clearData() => clearField(2); } +enum CellMetaChangeset_OneOfData { + data, + notSet +} + +class CellMetaChangeset extends $pb.GeneratedMessage { + static const $core.Map<$core.int, CellMetaChangeset_OneOfData> _CellMetaChangeset_OneOfDataByTag = { + 3 : CellMetaChangeset_OneOfData.data, + 0 : CellMetaChangeset_OneOfData.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellMetaChangeset', createEmptyInstance: create) + ..oo(0, [3]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') + ..hasRequiredFields = false + ; + + CellMetaChangeset._() : super(); + factory CellMetaChangeset({ + $core.String? rowId, + $core.String? fieldId, + $core.String? data, + }) { + final _result = create(); + if (rowId != null) { + _result.rowId = rowId; + } + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (data != null) { + _result.data = data; + } + return _result; + } + factory CellMetaChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CellMetaChangeset.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CellMetaChangeset clone() => CellMetaChangeset()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CellMetaChangeset copyWith(void Function(CellMetaChangeset) updates) => super.copyWith((message) => updates(message as CellMetaChangeset)) as CellMetaChangeset; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CellMetaChangeset create() => CellMetaChangeset._(); + CellMetaChangeset createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CellMetaChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CellMetaChangeset? _defaultInstance; + + CellMetaChangeset_OneOfData whichOneOfData() => _CellMetaChangeset_OneOfDataByTag[$_whichOneof(0)]!; + void clearOneOfData() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + $core.String get rowId => $_getSZ(0); + @$pb.TagNumber(1) + set rowId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasRowId() => $_has(0); + @$pb.TagNumber(1) + void clearRowId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get fieldId => $_getSZ(1); + @$pb.TagNumber(2) + set fieldId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasFieldId() => $_has(1); + @$pb.TagNumber(2) + void clearFieldId() => clearField(2); + + @$pb.TagNumber(3) + $core.String get 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); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 322b477e30..728367ea13 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -186,3 +186,18 @@ const CellMeta$json = const { /// Descriptor for `CellMeta`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List cellMetaDescriptor = $convert.base64Decode('CghDZWxsTWV0YRIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBISCgRkYXRhGAIgASgJUgRkYXRh'); +@$core.Deprecated('Use cellMetaChangesetDescriptor instead') +const CellMetaChangeset$json = const { + '1': 'CellMetaChangeset', + '2': const [ + const {'1': 'row_id', '3': 1, '4': 1, '5': 9, '10': 'rowId'}, + const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'data', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'data'}, + ], + '8': const [ + const {'1': 'one_of_data'}, + ], +}; + +/// Descriptor for `CellMetaChangeset`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List cellMetaChangesetDescriptor = $convert.base64Decode('ChFDZWxsTWV0YUNoYW5nZXNldBIVCgZyb3dfaWQYASABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAIgASgJUgdmaWVsZElkEhQKBGRhdGEYAyABKAlIAFIEZGF0YUINCgtvbmVfb2ZfZGF0YQ=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pb.dart new file mode 100644 index 0000000000..8481b81985 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pb.dart @@ -0,0 +1,58 @@ +/// +// Generated code. Do not modify. +// source: checkbox_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class CheckboxDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CheckboxDescription', createEmptyInstance: create) + ..aOB(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'isSelected') + ..hasRequiredFields = false + ; + + CheckboxDescription._() : super(); + factory CheckboxDescription({ + $core.bool? isSelected, + }) { + final _result = create(); + if (isSelected != null) { + _result.isSelected = isSelected; + } + return _result; + } + factory CheckboxDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CheckboxDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CheckboxDescription clone() => CheckboxDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CheckboxDescription copyWith(void Function(CheckboxDescription) updates) => super.copyWith((message) => updates(message as CheckboxDescription)) as CheckboxDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CheckboxDescription create() => CheckboxDescription._(); + CheckboxDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CheckboxDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CheckboxDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.bool get isSelected => $_getBF(0); + @$pb.TagNumber(1) + set isSelected($core.bool v) { $_setBool(0, v); } + @$pb.TagNumber(1) + $core.bool hasIsSelected() => $_has(0); + @$pb.TagNumber(1) + void clearIsSelected() => clearField(1); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbenum.dart new file mode 100644 index 0000000000..0070b08607 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbenum.dart @@ -0,0 +1,7 @@ +/// +// Generated code. Do not modify. +// source: checkbox_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart new file mode 100644 index 0000000000..6295b27033 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbjson.dart @@ -0,0 +1,20 @@ +/// +// Generated code. Do not modify. +// source: checkbox_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use checkboxDescriptionDescriptor instead') +const CheckboxDescription$json = const { + '1': 'CheckboxDescription', + '2': const [ + const {'1': 'is_selected', '3': 1, '4': 1, '5': 8, '10': 'isSelected'}, + ], +}; + +/// Descriptor for `CheckboxDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List checkboxDescriptionDescriptor = $convert.base64Decode('ChNDaGVja2JveERlc2NyaXB0aW9uEh8KC2lzX3NlbGVjdGVkGAEgASgIUgppc1NlbGVjdGVk'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbserver.dart new file mode 100644 index 0000000000..166969b429 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/checkbox_description.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: checkbox_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'checkbox_description.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pb.dart new file mode 100644 index 0000000000..a70bff6f3c --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pb.dart @@ -0,0 +1,76 @@ +/// +// Generated code. Do not modify. +// source: date_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'date_description.pbenum.dart'; + +export 'date_description.pbenum.dart'; + +class DateDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'DateDescription', createEmptyInstance: create) + ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dateFormat', $pb.PbFieldType.OE, defaultOrMaker: DateFormat.Local, valueOf: DateFormat.valueOf, enumValues: DateFormat.values) + ..e(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'timeFormat', $pb.PbFieldType.OE, defaultOrMaker: TimeFormat.TwelveHour, valueOf: TimeFormat.valueOf, enumValues: TimeFormat.values) + ..hasRequiredFields = false + ; + + DateDescription._() : super(); + factory DateDescription({ + DateFormat? dateFormat, + TimeFormat? timeFormat, + }) { + final _result = create(); + if (dateFormat != null) { + _result.dateFormat = dateFormat; + } + if (timeFormat != null) { + _result.timeFormat = timeFormat; + } + return _result; + } + factory DateDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory DateDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + DateDescription clone() => DateDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + DateDescription copyWith(void Function(DateDescription) updates) => super.copyWith((message) => updates(message as DateDescription)) as DateDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static DateDescription create() => DateDescription._(); + DateDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static DateDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static DateDescription? _defaultInstance; + + @$pb.TagNumber(1) + DateFormat get dateFormat => $_getN(0); + @$pb.TagNumber(1) + set dateFormat(DateFormat v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasDateFormat() => $_has(0); + @$pb.TagNumber(1) + void clearDateFormat() => clearField(1); + + @$pb.TagNumber(2) + TimeFormat get timeFormat => $_getN(1); + @$pb.TagNumber(2) + set timeFormat(TimeFormat v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasTimeFormat() => $_has(1); + @$pb.TagNumber(2) + void clearTimeFormat() => clearField(2); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbenum.dart new file mode 100644 index 0000000000..93ea01d9be --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbenum.dart @@ -0,0 +1,45 @@ +/// +// Generated code. Do not modify. +// source: date_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +// ignore_for_file: UNDEFINED_SHOWN_NAME +import 'dart:core' as $core; +import 'package:protobuf/protobuf.dart' as $pb; + +class DateFormat extends $pb.ProtobufEnum { + static const DateFormat Local = DateFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Local'); + static const DateFormat US = DateFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'US'); + static const DateFormat ISO = DateFormat._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ISO'); + static const DateFormat Friendly = DateFormat._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Friendly'); + + static const $core.List values = [ + Local, + US, + ISO, + Friendly, + ]; + + static final $core.Map<$core.int, DateFormat> _byValue = $pb.ProtobufEnum.initByValue(values); + static DateFormat? valueOf($core.int value) => _byValue[value]; + + const DateFormat._($core.int v, $core.String n) : super(v, n); +} + +class TimeFormat extends $pb.ProtobufEnum { + static const TimeFormat TwelveHour = TimeFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TwelveHour'); + static const TimeFormat TwentyFourHour = TimeFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TwentyFourHour'); + + static const $core.List values = [ + TwelveHour, + TwentyFourHour, + ]; + + static final $core.Map<$core.int, TimeFormat> _byValue = $pb.ProtobufEnum.initByValue(values); + static TimeFormat? valueOf($core.int value) => _byValue[value]; + + const TimeFormat._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbjson.dart new file mode 100644 index 0000000000..841db39005 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbjson.dart @@ -0,0 +1,45 @@ +/// +// Generated code. Do not modify. +// source: date_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use dateFormatDescriptor instead') +const DateFormat$json = const { + '1': 'DateFormat', + '2': const [ + const {'1': 'Local', '2': 0}, + const {'1': 'US', '2': 1}, + const {'1': 'ISO', '2': 2}, + const {'1': 'Friendly', '2': 3}, + ], +}; + +/// Descriptor for `DateFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List dateFormatDescriptor = $convert.base64Decode('CgpEYXRlRm9ybWF0EgkKBUxvY2FsEAASBgoCVVMQARIHCgNJU08QAhIMCghGcmllbmRseRAD'); +@$core.Deprecated('Use timeFormatDescriptor instead') +const TimeFormat$json = const { + '1': 'TimeFormat', + '2': const [ + const {'1': 'TwelveHour', '2': 0}, + const {'1': 'TwentyFourHour', '2': 1}, + ], +}; + +/// Descriptor for `TimeFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List timeFormatDescriptor = $convert.base64Decode('CgpUaW1lRm9ybWF0Eg4KClR3ZWx2ZUhvdXIQABISCg5Ud2VudHlGb3VySG91chAB'); +@$core.Deprecated('Use dateDescriptionDescriptor instead') +const DateDescription$json = const { + '1': 'DateDescription', + '2': const [ + const {'1': 'date_format', '3': 1, '4': 1, '5': 14, '6': '.DateFormat', '10': 'dateFormat'}, + const {'1': 'time_format', '3': 2, '4': 1, '5': 14, '6': '.TimeFormat', '10': 'timeFormat'}, + ], +}; + +/// Descriptor for `DateDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List dateDescriptionDescriptor = $convert.base64Decode('Cg9EYXRlRGVzY3JpcHRpb24SLAoLZGF0ZV9mb3JtYXQYASABKA4yCy5EYXRlRm9ybWF0UgpkYXRlRm9ybWF0EiwKC3RpbWVfZm9ybWF0GAIgASgOMgsuVGltZUZvcm1hdFIKdGltZUZvcm1hdA=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbserver.dart new file mode 100644 index 0000000000..dd4ff2c3c7 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_description.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: date_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'date_description.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart new file mode 100644 index 0000000000..395ac5c07f --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart @@ -0,0 +1,118 @@ +/// +// Generated code. Do not modify. +// source: number_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'number_description.pbenum.dart'; + +export 'number_description.pbenum.dart'; + +class NumberDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'NumberDescription', createEmptyInstance: create) + ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'money', $pb.PbFieldType.OE, defaultOrMaker: MoneySymbol.CNY, valueOf: MoneySymbol.valueOf, enumValues: MoneySymbol.values) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scale', $pb.PbFieldType.OU3) + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'symbol') + ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signPositive') + ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..hasRequiredFields = false + ; + + NumberDescription._() : super(); + factory NumberDescription({ + MoneySymbol? money, + $core.int? scale, + $core.String? symbol, + $core.bool? signPositive, + $core.String? name, + }) { + final _result = create(); + if (money != null) { + _result.money = money; + } + if (scale != null) { + _result.scale = scale; + } + if (symbol != null) { + _result.symbol = symbol; + } + if (signPositive != null) { + _result.signPositive = signPositive; + } + if (name != null) { + _result.name = name; + } + return _result; + } + factory NumberDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory NumberDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + NumberDescription clone() => NumberDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + NumberDescription copyWith(void Function(NumberDescription) updates) => super.copyWith((message) => updates(message as NumberDescription)) as NumberDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static NumberDescription create() => NumberDescription._(); + NumberDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static NumberDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static NumberDescription? _defaultInstance; + + @$pb.TagNumber(1) + MoneySymbol get money => $_getN(0); + @$pb.TagNumber(1) + set money(MoneySymbol v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasMoney() => $_has(0); + @$pb.TagNumber(1) + void clearMoney() => clearField(1); + + @$pb.TagNumber(2) + $core.int get scale => $_getIZ(1); + @$pb.TagNumber(2) + set scale($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasScale() => $_has(1); + @$pb.TagNumber(2) + void clearScale() => clearField(2); + + @$pb.TagNumber(3) + $core.String get symbol => $_getSZ(2); + @$pb.TagNumber(3) + set symbol($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasSymbol() => $_has(2); + @$pb.TagNumber(3) + void clearSymbol() => clearField(3); + + @$pb.TagNumber(4) + $core.bool get signPositive => $_getBF(3); + @$pb.TagNumber(4) + set signPositive($core.bool v) { $_setBool(3, v); } + @$pb.TagNumber(4) + $core.bool hasSignPositive() => $_has(3); + @$pb.TagNumber(4) + void clearSignPositive() => clearField(4); + + @$pb.TagNumber(5) + $core.String get name => $_getSZ(4); + @$pb.TagNumber(5) + set name($core.String v) { $_setString(4, v); } + @$pb.TagNumber(5) + $core.bool hasName() => $_has(4); + @$pb.TagNumber(5) + void clearName() => clearField(5); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart new file mode 100644 index 0000000000..daae771fce --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart @@ -0,0 +1,28 @@ +/// +// Generated code. Do not modify. +// source: number_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +// ignore_for_file: UNDEFINED_SHOWN_NAME +import 'dart:core' as $core; +import 'package:protobuf/protobuf.dart' as $pb; + +class MoneySymbol extends $pb.ProtobufEnum { + static const MoneySymbol CNY = MoneySymbol._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CNY'); + static const MoneySymbol EUR = MoneySymbol._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EUR'); + static const MoneySymbol USD = MoneySymbol._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'USD'); + + static const $core.List values = [ + CNY, + EUR, + USD, + ]; + + static final $core.Map<$core.int, MoneySymbol> _byValue = $pb.ProtobufEnum.initByValue(values); + static MoneySymbol? valueOf($core.int value) => _byValue[value]; + + const MoneySymbol._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart new file mode 100644 index 0000000000..4a0c8db75a --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart @@ -0,0 +1,36 @@ +/// +// Generated code. Do not modify. +// source: number_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use moneySymbolDescriptor instead') +const MoneySymbol$json = const { + '1': 'MoneySymbol', + '2': const [ + const {'1': 'CNY', '2': 0}, + const {'1': 'EUR', '2': 1}, + const {'1': 'USD', '2': 2}, + ], +}; + +/// Descriptor for `MoneySymbol`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List moneySymbolDescriptor = $convert.base64Decode('CgtNb25leVN5bWJvbBIHCgNDTlkQABIHCgNFVVIQARIHCgNVU0QQAg=='); +@$core.Deprecated('Use numberDescriptionDescriptor instead') +const NumberDescription$json = const { + '1': 'NumberDescription', + '2': const [ + const {'1': 'money', '3': 1, '4': 1, '5': 14, '6': '.MoneySymbol', '10': 'money'}, + const {'1': 'scale', '3': 2, '4': 1, '5': 13, '10': 'scale'}, + const {'1': 'symbol', '3': 3, '4': 1, '5': 9, '10': 'symbol'}, + const {'1': 'sign_positive', '3': 4, '4': 1, '5': 8, '10': 'signPositive'}, + const {'1': 'name', '3': 5, '4': 1, '5': 9, '10': 'name'}, + ], +}; + +/// Descriptor for `NumberDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List numberDescriptionDescriptor = $convert.base64Decode('ChFOdW1iZXJEZXNjcmlwdGlvbhIiCgVtb25leRgBIAEoDjIMLk1vbmV5U3ltYm9sUgVtb25leRIUCgVzY2FsZRgCIAEoDVIFc2NhbGUSFgoGc3ltYm9sGAMgASgJUgZzeW1ib2wSIwoNc2lnbl9wb3NpdGl2ZRgEIAEoCFIMc2lnblBvc2l0aXZlEhIKBG5hbWUYBSABKAlSBG5hbWU='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbserver.dart new file mode 100644 index 0000000000..58225a92b7 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: number_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'number_description.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart index b7eb77d660..0ad090edd5 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart @@ -1,3 +1,7 @@ // Auto-generated, do not edit -export './type_options.pb.dart'; +export './date_description.pb.dart'; +export './text_description.pb.dart'; +export './checkbox_description.pb.dart'; +export './selection_description.pb.dart'; export './event_map.pb.dart'; +export './number_description.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pb.dart new file mode 100644 index 0000000000..27b2fa8431 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pb.dart @@ -0,0 +1,196 @@ +/// +// Generated code. Do not modify. +// source: selection_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class SingleSelectDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SingleSelectDescription', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'options', $pb.PbFieldType.PM, subBuilder: SelectOption.create) + ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'disableColor') + ..hasRequiredFields = false + ; + + SingleSelectDescription._() : super(); + factory SingleSelectDescription({ + $core.Iterable? options, + $core.bool? disableColor, + }) { + final _result = create(); + if (options != null) { + _result.options.addAll(options); + } + if (disableColor != null) { + _result.disableColor = disableColor; + } + return _result; + } + factory SingleSelectDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory SingleSelectDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SingleSelectDescription clone() => SingleSelectDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SingleSelectDescription copyWith(void Function(SingleSelectDescription) updates) => super.copyWith((message) => updates(message as SingleSelectDescription)) as SingleSelectDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static SingleSelectDescription create() => SingleSelectDescription._(); + SingleSelectDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SingleSelectDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static SingleSelectDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get options => $_getList(0); + + @$pb.TagNumber(2) + $core.bool get disableColor => $_getBF(1); + @$pb.TagNumber(2) + set disableColor($core.bool v) { $_setBool(1, v); } + @$pb.TagNumber(2) + $core.bool hasDisableColor() => $_has(1); + @$pb.TagNumber(2) + void clearDisableColor() => clearField(2); +} + +class MultiSelectDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'MultiSelectDescription', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'options', $pb.PbFieldType.PM, subBuilder: SelectOption.create) + ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'disableColor') + ..hasRequiredFields = false + ; + + MultiSelectDescription._() : super(); + factory MultiSelectDescription({ + $core.Iterable? options, + $core.bool? disableColor, + }) { + final _result = create(); + if (options != null) { + _result.options.addAll(options); + } + if (disableColor != null) { + _result.disableColor = disableColor; + } + return _result; + } + factory MultiSelectDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory MultiSelectDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + MultiSelectDescription clone() => MultiSelectDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + MultiSelectDescription copyWith(void Function(MultiSelectDescription) updates) => super.copyWith((message) => updates(message as MultiSelectDescription)) as MultiSelectDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static MultiSelectDescription create() => MultiSelectDescription._(); + MultiSelectDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static MultiSelectDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static MultiSelectDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get options => $_getList(0); + + @$pb.TagNumber(2) + $core.bool get disableColor => $_getBF(1); + @$pb.TagNumber(2) + set disableColor($core.bool v) { $_setBool(1, v); } + @$pb.TagNumber(2) + $core.bool hasDisableColor() => $_has(1); + @$pb.TagNumber(2) + void clearDisableColor() => clearField(2); +} + +class SelectOption extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOption', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'color') + ..hasRequiredFields = false + ; + + SelectOption._() : super(); + factory SelectOption({ + $core.String? id, + $core.String? name, + $core.String? color, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (name != null) { + _result.name = name; + } + if (color != null) { + _result.color = color; + } + return _result; + } + factory SelectOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory SelectOption.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SelectOption clone() => SelectOption()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SelectOption copyWith(void Function(SelectOption) updates) => super.copyWith((message) => updates(message as SelectOption)) as SelectOption; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static SelectOption create() => SelectOption._(); + SelectOption createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SelectOption getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static SelectOption? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get name => $_getSZ(1); + @$pb.TagNumber(2) + set name($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasName() => $_has(1); + @$pb.TagNumber(2) + void clearName() => clearField(2); + + @$pb.TagNumber(3) + $core.String get color => $_getSZ(2); + @$pb.TagNumber(3) + set color($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasColor() => $_has(2); + @$pb.TagNumber(3) + void clearColor() => clearField(3); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbenum.dart new file mode 100644 index 0000000000..6688bc34c9 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbenum.dart @@ -0,0 +1,7 @@ +/// +// Generated code. Do not modify. +// source: selection_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbjson.dart new file mode 100644 index 0000000000..6bb0c9e4db --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbjson.dart @@ -0,0 +1,44 @@ +/// +// Generated code. Do not modify. +// source: selection_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use singleSelectDescriptionDescriptor instead') +const SingleSelectDescription$json = const { + '1': 'SingleSelectDescription', + '2': const [ + const {'1': 'options', '3': 1, '4': 3, '5': 11, '6': '.SelectOption', '10': 'options'}, + const {'1': 'disable_color', '3': 2, '4': 1, '5': 8, '10': 'disableColor'}, + ], +}; + +/// Descriptor for `SingleSelectDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List singleSelectDescriptionDescriptor = $convert.base64Decode('ChdTaW5nbGVTZWxlY3REZXNjcmlwdGlvbhInCgdvcHRpb25zGAEgAygLMg0uU2VsZWN0T3B0aW9uUgdvcHRpb25zEiMKDWRpc2FibGVfY29sb3IYAiABKAhSDGRpc2FibGVDb2xvcg=='); +@$core.Deprecated('Use multiSelectDescriptionDescriptor instead') +const MultiSelectDescription$json = const { + '1': 'MultiSelectDescription', + '2': const [ + const {'1': 'options', '3': 1, '4': 3, '5': 11, '6': '.SelectOption', '10': 'options'}, + const {'1': 'disable_color', '3': 2, '4': 1, '5': 8, '10': 'disableColor'}, + ], +}; + +/// Descriptor for `MultiSelectDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List multiSelectDescriptionDescriptor = $convert.base64Decode('ChZNdWx0aVNlbGVjdERlc2NyaXB0aW9uEicKB29wdGlvbnMYASADKAsyDS5TZWxlY3RPcHRpb25SB29wdGlvbnMSIwoNZGlzYWJsZV9jb2xvchgCIAEoCFIMZGlzYWJsZUNvbG9y'); +@$core.Deprecated('Use selectOptionDescriptor instead') +const SelectOption$json = const { + '1': 'SelectOption', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, + const {'1': 'color', '3': 3, '4': 1, '5': 9, '10': 'color'}, + ], +}; + +/// Descriptor for `SelectOption`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List selectOptionDescriptor = $convert.base64Decode('CgxTZWxlY3RPcHRpb24SDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSFAoFY29sb3IYAyABKAlSBWNvbG9y'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbserver.dart new file mode 100644 index 0000000000..f55cbba1ec --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_description.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: selection_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'selection_description.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pb.dart new file mode 100644 index 0000000000..9434b2fc90 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pb.dart @@ -0,0 +1,58 @@ +/// +// Generated code. Do not modify. +// source: text_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class RichTextDescription extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RichTextDescription', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'format') + ..hasRequiredFields = false + ; + + RichTextDescription._() : super(); + factory RichTextDescription({ + $core.String? format, + }) { + final _result = create(); + if (format != null) { + _result.format = format; + } + return _result; + } + factory RichTextDescription.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RichTextDescription.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RichTextDescription clone() => RichTextDescription()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RichTextDescription copyWith(void Function(RichTextDescription) updates) => super.copyWith((message) => updates(message as RichTextDescription)) as RichTextDescription; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RichTextDescription create() => RichTextDescription._(); + RichTextDescription createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RichTextDescription getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RichTextDescription? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get format => $_getSZ(0); + @$pb.TagNumber(1) + set format($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasFormat() => $_has(0); + @$pb.TagNumber(1) + void clearFormat() => clearField(1); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbenum.dart new file mode 100644 index 0000000000..e01054c586 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbenum.dart @@ -0,0 +1,7 @@ +/// +// Generated code. Do not modify. +// source: text_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbjson.dart new file mode 100644 index 0000000000..fdf2098d47 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbjson.dart @@ -0,0 +1,20 @@ +/// +// Generated code. Do not modify. +// source: text_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use richTextDescriptionDescriptor instead') +const RichTextDescription$json = const { + '1': 'RichTextDescription', + '2': const [ + const {'1': 'format', '3': 1, '4': 1, '5': 9, '10': 'format'}, + ], +}; + +/// Descriptor for `RichTextDescription`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List richTextDescriptionDescriptor = $convert.base64Decode('ChNSaWNoVGV4dERlc2NyaXB0aW9uEhYKBmZvcm1hdBgBIAEoCVIGZm9ybWF0'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbserver.dart new file mode 100644 index 0000000000..2a02dd56b1 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/text_description.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: text_description.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'text_description.pb.dart'; + diff --git a/frontend/rust-lib/flowy-grid/Flowy.toml b/frontend/rust-lib/flowy-grid/Flowy.toml index fc5c01c773..4d1a277df3 100644 --- a/frontend/rust-lib/flowy-grid/Flowy.toml +++ b/frontend/rust-lib/flowy-grid/Flowy.toml @@ -1,3 +1,3 @@ -proto_crates = ["src/event_map.rs", "src/services/field/type_options.rs"] +proto_crates = ["src/event_map.rs", "src/services/cell/description"] event_files = ["src/event_map.rs"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 22dff6e191..5aa786431b 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -24,7 +24,7 @@ pub(crate) async fn get_rows_handler( ) -> DataResult { let payload: QueryRowPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_row: RepeatedRow = editor.get_rows(payload.row_orders).await?.into(); + let repeated_row: RepeatedRow = editor.get_rows(Some(payload.row_orders)).await?.into(); data_result(repeated_row) } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/checkbox_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/checkbox_description.rs new file mode 100644 index 0000000000..276617efbd --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/checkbox_description.rs @@ -0,0 +1,193 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `checkbox_description.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct CheckboxDescription { + // message fields + pub is_selected: bool, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CheckboxDescription { + fn default() -> &'a CheckboxDescription { + ::default_instance() + } +} + +impl CheckboxDescription { + pub fn new() -> CheckboxDescription { + ::std::default::Default::default() + } + + // bool is_selected = 1; + + + pub fn get_is_selected(&self) -> bool { + self.is_selected + } + pub fn clear_is_selected(&mut self) { + self.is_selected = false; + } + + // Param is passed by value, moved + pub fn set_is_selected(&mut self, v: bool) { + self.is_selected = v; + } +} + +impl ::protobuf::Message for CheckboxDescription { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.is_selected = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.is_selected != false { + my_size += 2; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.is_selected != false { + os.write_bool(1, self.is_selected)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> CheckboxDescription { + CheckboxDescription::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "is_selected", + |m: &CheckboxDescription| { &m.is_selected }, + |m: &mut CheckboxDescription| { &mut m.is_selected }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CheckboxDescription", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CheckboxDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CheckboxDescription::new) + } +} + +impl ::protobuf::Clear for CheckboxDescription { + fn clear(&mut self) { + self.is_selected = false; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CheckboxDescription { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CheckboxDescription { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x1acheckbox_description.proto\"6\n\x13CheckboxDescription\x12\x1f\n\ + \x0bis_selected\x18\x01\x20\x01(\x08R\nisSelectedb\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/date_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/date_description.rs new file mode 100644 index 0000000000..05b2bc6a0f --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/date_description.rs @@ -0,0 +1,330 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `date_description.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct DateDescription { + // message fields + pub date_format: DateFormat, + pub time_format: TimeFormat, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a DateDescription { + fn default() -> &'a DateDescription { + ::default_instance() + } +} + +impl DateDescription { + pub fn new() -> DateDescription { + ::std::default::Default::default() + } + + // .DateFormat date_format = 1; + + + pub fn get_date_format(&self) -> DateFormat { + self.date_format + } + pub fn clear_date_format(&mut self) { + self.date_format = DateFormat::Local; + } + + // Param is passed by value, moved + pub fn set_date_format(&mut self, v: DateFormat) { + self.date_format = v; + } + + // .TimeFormat time_format = 2; + + + pub fn get_time_format(&self) -> TimeFormat { + self.time_format + } + pub fn clear_time_format(&mut self) { + self.time_format = TimeFormat::TwelveHour; + } + + // Param is passed by value, moved + pub fn set_time_format(&mut self, v: TimeFormat) { + self.time_format = v; + } +} + +impl ::protobuf::Message for DateDescription { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.date_format, 1, &mut self.unknown_fields)? + }, + 2 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.time_format, 2, &mut self.unknown_fields)? + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.date_format != DateFormat::Local { + my_size += ::protobuf::rt::enum_size(1, self.date_format); + } + if self.time_format != TimeFormat::TwelveHour { + my_size += ::protobuf::rt::enum_size(2, self.time_format); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.date_format != DateFormat::Local { + os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.date_format))?; + } + if self.time_format != TimeFormat::TwelveHour { + os.write_enum(2, ::protobuf::ProtobufEnum::value(&self.time_format))?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> DateDescription { + DateDescription::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "date_format", + |m: &DateDescription| { &m.date_format }, + |m: &mut DateDescription| { &mut m.date_format }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "time_format", + |m: &DateDescription| { &m.time_format }, + |m: &mut DateDescription| { &mut m.time_format }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "DateDescription", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static DateDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(DateDescription::new) + } +} + +impl ::protobuf::Clear for DateDescription { + fn clear(&mut self) { + self.date_format = DateFormat::Local; + self.time_format = TimeFormat::TwelveHour; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for DateDescription { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for DateDescription { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum DateFormat { + Local = 0, + US = 1, + ISO = 2, + Friendly = 3, +} + +impl ::protobuf::ProtobufEnum for DateFormat { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(DateFormat::Local), + 1 => ::std::option::Option::Some(DateFormat::US), + 2 => ::std::option::Option::Some(DateFormat::ISO), + 3 => ::std::option::Option::Some(DateFormat::Friendly), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [DateFormat] = &[ + DateFormat::Local, + DateFormat::US, + DateFormat::ISO, + DateFormat::Friendly, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("DateFormat", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for DateFormat { +} + +impl ::std::default::Default for DateFormat { + fn default() -> Self { + DateFormat::Local + } +} + +impl ::protobuf::reflect::ProtobufValue for DateFormat { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum TimeFormat { + TwelveHour = 0, + TwentyFourHour = 1, +} + +impl ::protobuf::ProtobufEnum for TimeFormat { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(TimeFormat::TwelveHour), + 1 => ::std::option::Option::Some(TimeFormat::TwentyFourHour), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [TimeFormat] = &[ + TimeFormat::TwelveHour, + TimeFormat::TwentyFourHour, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("TimeFormat", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for TimeFormat { +} + +impl ::std::default::Default for TimeFormat { + fn default() -> Self { + TimeFormat::TwelveHour + } +} + +impl ::protobuf::reflect::ProtobufValue for TimeFormat { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x16date_description.proto\"m\n\x0fDateDescription\x12,\n\x0bdate_form\ + at\x18\x01\x20\x01(\x0e2\x0b.DateFormatR\ndateFormat\x12,\n\x0btime_form\ + at\x18\x02\x20\x01(\x0e2\x0b.TimeFormatR\ntimeFormat*6\n\nDateFormat\x12\ + \t\n\x05Local\x10\0\x12\x06\n\x02US\x10\x01\x12\x07\n\x03ISO\x10\x02\x12\ + \x0c\n\x08Friendly\x10\x03*0\n\nTimeFormat\x12\x0e\n\nTwelveHour\x10\0\ + \x12\x12\n\x0eTwentyFourHour\x10\x01b\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs index d9c75efb74..fb32dca3f2 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs @@ -1,8 +1,20 @@ #![cfg_attr(rustfmt, rustfmt::skip)] // Auto-generated, do not edit -mod type_options; -pub use type_options::*; +mod date_description; +pub use date_description::*; + +mod text_description; +pub use text_description::*; + +mod checkbox_description; +pub use checkbox_description::*; + +mod selection_description; +pub use selection_description::*; mod event_map; pub use event_map::*; + +mod number_description; +pub use number_description::*; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs new file mode 100644 index 0000000000..17bdb557e6 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs @@ -0,0 +1,401 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `number_description.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct NumberDescription { + // message fields + pub money: MoneySymbol, + pub scale: u32, + pub symbol: ::std::string::String, + pub sign_positive: bool, + pub name: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a NumberDescription { + fn default() -> &'a NumberDescription { + ::default_instance() + } +} + +impl NumberDescription { + pub fn new() -> NumberDescription { + ::std::default::Default::default() + } + + // .MoneySymbol money = 1; + + + pub fn get_money(&self) -> MoneySymbol { + self.money + } + pub fn clear_money(&mut self) { + self.money = MoneySymbol::CNY; + } + + // Param is passed by value, moved + pub fn set_money(&mut self, v: MoneySymbol) { + self.money = v; + } + + // uint32 scale = 2; + + + pub fn get_scale(&self) -> u32 { + self.scale + } + pub fn clear_scale(&mut self) { + self.scale = 0; + } + + // Param is passed by value, moved + pub fn set_scale(&mut self, v: u32) { + self.scale = v; + } + + // string symbol = 3; + + + pub fn get_symbol(&self) -> &str { + &self.symbol + } + pub fn clear_symbol(&mut self) { + self.symbol.clear(); + } + + // Param is passed by value, moved + pub fn set_symbol(&mut self, v: ::std::string::String) { + self.symbol = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_symbol(&mut self) -> &mut ::std::string::String { + &mut self.symbol + } + + // Take field + pub fn take_symbol(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.symbol, ::std::string::String::new()) + } + + // bool sign_positive = 4; + + + pub fn get_sign_positive(&self) -> bool { + self.sign_positive + } + pub fn clear_sign_positive(&mut self) { + self.sign_positive = false; + } + + // Param is passed by value, moved + pub fn set_sign_positive(&mut self, v: bool) { + self.sign_positive = v; + } + + // string name = 5; + + + pub fn get_name(&self) -> &str { + &self.name + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + &mut self.name + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.name, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for NumberDescription { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.money, 1, &mut self.unknown_fields)? + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_uint32()?; + self.scale = tmp; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.symbol)?; + }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.sign_positive = tmp; + }, + 5 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.money != MoneySymbol::CNY { + my_size += ::protobuf::rt::enum_size(1, self.money); + } + if self.scale != 0 { + my_size += ::protobuf::rt::value_size(2, self.scale, ::protobuf::wire_format::WireTypeVarint); + } + if !self.symbol.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.symbol); + } + if self.sign_positive != false { + my_size += 2; + } + if !self.name.is_empty() { + my_size += ::protobuf::rt::string_size(5, &self.name); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.money != MoneySymbol::CNY { + os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.money))?; + } + if self.scale != 0 { + os.write_uint32(2, self.scale)?; + } + if !self.symbol.is_empty() { + os.write_string(3, &self.symbol)?; + } + if self.sign_positive != false { + os.write_bool(4, self.sign_positive)?; + } + if !self.name.is_empty() { + os.write_string(5, &self.name)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> NumberDescription { + NumberDescription::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "money", + |m: &NumberDescription| { &m.money }, + |m: &mut NumberDescription| { &mut m.money }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint32>( + "scale", + |m: &NumberDescription| { &m.scale }, + |m: &mut NumberDescription| { &mut m.scale }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "symbol", + |m: &NumberDescription| { &m.symbol }, + |m: &mut NumberDescription| { &mut m.symbol }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "sign_positive", + |m: &NumberDescription| { &m.sign_positive }, + |m: &mut NumberDescription| { &mut m.sign_positive }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &NumberDescription| { &m.name }, + |m: &mut NumberDescription| { &mut m.name }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "NumberDescription", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static NumberDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(NumberDescription::new) + } +} + +impl ::protobuf::Clear for NumberDescription { + fn clear(&mut self) { + self.money = MoneySymbol::CNY; + self.scale = 0; + self.symbol.clear(); + self.sign_positive = false; + self.name.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for NumberDescription { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for NumberDescription { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum MoneySymbol { + CNY = 0, + EUR = 1, + USD = 2, +} + +impl ::protobuf::ProtobufEnum for MoneySymbol { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(MoneySymbol::CNY), + 1 => ::std::option::Option::Some(MoneySymbol::EUR), + 2 => ::std::option::Option::Some(MoneySymbol::USD), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [MoneySymbol] = &[ + MoneySymbol::CNY, + MoneySymbol::EUR, + MoneySymbol::USD, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("MoneySymbol", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for MoneySymbol { +} + +impl ::std::default::Default for MoneySymbol { + fn default() -> Self { + MoneySymbol::CNY + } +} + +impl ::protobuf::reflect::ProtobufValue for MoneySymbol { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x18number_description.proto\"\x9e\x01\n\x11NumberDescription\x12\"\n\ + \x05money\x18\x01\x20\x01(\x0e2\x0c.MoneySymbolR\x05money\x12\x14\n\x05s\ + cale\x18\x02\x20\x01(\rR\x05scale\x12\x16\n\x06symbol\x18\x03\x20\x01(\t\ + R\x06symbol\x12#\n\rsign_positive\x18\x04\x20\x01(\x08R\x0csignPositive\ + \x12\x12\n\x04name\x18\x05\x20\x01(\tR\x04name*(\n\x0bMoneySymbol\x12\ + \x07\n\x03CNY\x10\0\x12\x07\n\x03EUR\x10\x01\x12\x07\n\x03USD\x10\x02b\ + \x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_description.rs new file mode 100644 index 0000000000..9feda09402 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_description.rs @@ -0,0 +1,692 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `selection_description.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct SingleSelectDescription { + // message fields + pub options: ::protobuf::RepeatedField, + pub disable_color: bool, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a SingleSelectDescription { + fn default() -> &'a SingleSelectDescription { + ::default_instance() + } +} + +impl SingleSelectDescription { + pub fn new() -> SingleSelectDescription { + ::std::default::Default::default() + } + + // repeated .SelectOption options = 1; + + + pub fn get_options(&self) -> &[SelectOption] { + &self.options + } + pub fn clear_options(&mut self) { + self.options.clear(); + } + + // Param is passed by value, moved + pub fn set_options(&mut self, v: ::protobuf::RepeatedField) { + self.options = v; + } + + // Mutable pointer to the field. + pub fn mut_options(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.options + } + + // Take field + pub fn take_options(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.options, ::protobuf::RepeatedField::new()) + } + + // bool disable_color = 2; + + + pub fn get_disable_color(&self) -> bool { + self.disable_color + } + pub fn clear_disable_color(&mut self) { + self.disable_color = false; + } + + // Param is passed by value, moved + pub fn set_disable_color(&mut self, v: bool) { + self.disable_color = v; + } +} + +impl ::protobuf::Message for SingleSelectDescription { + fn is_initialized(&self) -> bool { + for v in &self.options { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.options)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.disable_color = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.options { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + if self.disable_color != false { + my_size += 2; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.options { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + if self.disable_color != false { + os.write_bool(2, self.disable_color)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> SingleSelectDescription { + SingleSelectDescription::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "options", + |m: &SingleSelectDescription| { &m.options }, + |m: &mut SingleSelectDescription| { &mut m.options }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "disable_color", + |m: &SingleSelectDescription| { &m.disable_color }, + |m: &mut SingleSelectDescription| { &mut m.disable_color }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SingleSelectDescription", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static SingleSelectDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SingleSelectDescription::new) + } +} + +impl ::protobuf::Clear for SingleSelectDescription { + fn clear(&mut self) { + self.options.clear(); + self.disable_color = false; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for SingleSelectDescription { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SingleSelectDescription { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MultiSelectDescription { + // message fields + pub options: ::protobuf::RepeatedField, + pub disable_color: bool, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MultiSelectDescription { + fn default() -> &'a MultiSelectDescription { + ::default_instance() + } +} + +impl MultiSelectDescription { + pub fn new() -> MultiSelectDescription { + ::std::default::Default::default() + } + + // repeated .SelectOption options = 1; + + + pub fn get_options(&self) -> &[SelectOption] { + &self.options + } + pub fn clear_options(&mut self) { + self.options.clear(); + } + + // Param is passed by value, moved + pub fn set_options(&mut self, v: ::protobuf::RepeatedField) { + self.options = v; + } + + // Mutable pointer to the field. + pub fn mut_options(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.options + } + + // Take field + pub fn take_options(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.options, ::protobuf::RepeatedField::new()) + } + + // bool disable_color = 2; + + + pub fn get_disable_color(&self) -> bool { + self.disable_color + } + pub fn clear_disable_color(&mut self) { + self.disable_color = false; + } + + // Param is passed by value, moved + pub fn set_disable_color(&mut self, v: bool) { + self.disable_color = v; + } +} + +impl ::protobuf::Message for MultiSelectDescription { + fn is_initialized(&self) -> bool { + for v in &self.options { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.options)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.disable_color = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.options { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + if self.disable_color != false { + my_size += 2; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.options { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + if self.disable_color != false { + os.write_bool(2, self.disable_color)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MultiSelectDescription { + MultiSelectDescription::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "options", + |m: &MultiSelectDescription| { &m.options }, + |m: &mut MultiSelectDescription| { &mut m.options }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "disable_color", + |m: &MultiSelectDescription| { &m.disable_color }, + |m: &mut MultiSelectDescription| { &mut m.disable_color }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MultiSelectDescription", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MultiSelectDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MultiSelectDescription::new) + } +} + +impl ::protobuf::Clear for MultiSelectDescription { + fn clear(&mut self) { + self.options.clear(); + self.disable_color = false; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MultiSelectDescription { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MultiSelectDescription { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct SelectOption { + // message fields + pub id: ::std::string::String, + pub name: ::std::string::String, + pub color: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a SelectOption { + fn default() -> &'a SelectOption { + ::default_instance() + } +} + +impl SelectOption { + pub fn new() -> SelectOption { + ::std::default::Default::default() + } + + // string id = 1; + + + pub fn get_id(&self) -> &str { + &self.id + } + pub fn clear_id(&mut self) { + self.id.clear(); + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: ::std::string::String) { + self.id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id + } + + // Take field + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) + } + + // string name = 2; + + + pub fn get_name(&self) -> &str { + &self.name + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + &mut self.name + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.name, ::std::string::String::new()) + } + + // string color = 3; + + + pub fn get_color(&self) -> &str { + &self.color + } + pub fn clear_color(&mut self) { + self.color.clear(); + } + + // Param is passed by value, moved + pub fn set_color(&mut self, v: ::std::string::String) { + self.color = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_color(&mut self) -> &mut ::std::string::String { + &mut self.color + } + + // Take field + pub fn take_color(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.color, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for SelectOption { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.color)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + if !self.name.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.name); + } + if !self.color.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.color); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + if !self.name.is_empty() { + os.write_string(2, &self.name)?; + } + if !self.color.is_empty() { + os.write_string(3, &self.color)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> SelectOption { + SelectOption::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &SelectOption| { &m.id }, + |m: &mut SelectOption| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &SelectOption| { &m.name }, + |m: &mut SelectOption| { &mut m.name }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "color", + |m: &SelectOption| { &m.color }, + |m: &mut SelectOption| { &mut m.color }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SelectOption", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static SelectOption { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SelectOption::new) + } +} + +impl ::protobuf::Clear for SelectOption { + fn clear(&mut self) { + self.id.clear(); + self.name.clear(); + self.color.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for SelectOption { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SelectOption { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x1bselection_description.proto\"g\n\x17SingleSelectDescription\x12'\n\ + \x07options\x18\x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x12#\n\rdis\ + able_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"f\n\x16MultiSelectDesc\ + ription\x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.SelectOptionR\x07optio\ + ns\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"H\n\x0cS\ + electOption\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\ + \x18\x02\x20\x01(\tR\x04name\x12\x14\n\x05color\x18\x03\x20\x01(\tR\x05c\ + olorb\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/text_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/text_description.rs new file mode 100644 index 0000000000..ca2d720e14 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/text_description.rs @@ -0,0 +1,200 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `text_description.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(PartialEq,Clone,Default)] +pub struct RichTextDescription { + // message fields + pub format: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RichTextDescription { + fn default() -> &'a RichTextDescription { + ::default_instance() + } +} + +impl RichTextDescription { + pub fn new() -> RichTextDescription { + ::std::default::Default::default() + } + + // string format = 1; + + + pub fn get_format(&self) -> &str { + &self.format + } + pub fn clear_format(&mut self) { + self.format.clear(); + } + + // Param is passed by value, moved + pub fn set_format(&mut self, v: ::std::string::String) { + self.format = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_format(&mut self) -> &mut ::std::string::String { + &mut self.format + } + + // Take field + pub fn take_format(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.format, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for RichTextDescription { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.format)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.format.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.format); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.format.is_empty() { + os.write_string(1, &self.format)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RichTextDescription { + RichTextDescription::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "format", + |m: &RichTextDescription| { &m.format }, + |m: &mut RichTextDescription| { &mut m.format }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RichTextDescription", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RichTextDescription { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RichTextDescription::new) + } +} + +impl ::protobuf::Clear for RichTextDescription { + fn clear(&mut self) { + self.format.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RichTextDescription { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RichTextDescription { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x16text_description.proto\"-\n\x13RichTextDescription\x12\x16\n\x06fo\ + rmat\x18\x01\x20\x01(\tR\x06formatb\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/type_options.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/type_options.rs deleted file mode 100644 index cda2c556c3..0000000000 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/type_options.rs +++ /dev/null @@ -1,1656 +0,0 @@ -// This file is generated by rust-protobuf 2.25.2. Do not edit -// @generated - -// https://github.com/rust-lang/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy::all)] - -#![allow(unused_attributes)] -#![cfg_attr(rustfmt, rustfmt::skip)] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unused_imports)] -#![allow(unused_results)] -//! Generated file from `type_options.proto` - -/// Generated files are compatible only with the same version -/// of protobuf runtime. -// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; - -#[derive(PartialEq,Clone,Default)] -pub struct RichTextDescription { - // message fields - pub format: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RichTextDescription { - fn default() -> &'a RichTextDescription { - ::default_instance() - } -} - -impl RichTextDescription { - pub fn new() -> RichTextDescription { - ::std::default::Default::default() - } - - // string format = 1; - - - pub fn get_format(&self) -> &str { - &self.format - } - pub fn clear_format(&mut self) { - self.format.clear(); - } - - // Param is passed by value, moved - pub fn set_format(&mut self, v: ::std::string::String) { - self.format = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_format(&mut self) -> &mut ::std::string::String { - &mut self.format - } - - // Take field - pub fn take_format(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.format, ::std::string::String::new()) - } -} - -impl ::protobuf::Message for RichTextDescription { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.format)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.format.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.format); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.format.is_empty() { - os.write_string(1, &self.format)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RichTextDescription { - RichTextDescription::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "format", - |m: &RichTextDescription| { &m.format }, - |m: &mut RichTextDescription| { &mut m.format }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RichTextDescription", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RichTextDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RichTextDescription::new) - } -} - -impl ::protobuf::Clear for RichTextDescription { - fn clear(&mut self) { - self.format.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RichTextDescription { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RichTextDescription { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct CheckboxDescription { - // message fields - pub is_selected: bool, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a CheckboxDescription { - fn default() -> &'a CheckboxDescription { - ::default_instance() - } -} - -impl CheckboxDescription { - pub fn new() -> CheckboxDescription { - ::std::default::Default::default() - } - - // bool is_selected = 1; - - - pub fn get_is_selected(&self) -> bool { - self.is_selected - } - pub fn clear_is_selected(&mut self) { - self.is_selected = false; - } - - // Param is passed by value, moved - pub fn set_is_selected(&mut self, v: bool) { - self.is_selected = v; - } -} - -impl ::protobuf::Message for CheckboxDescription { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.is_selected = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if self.is_selected != false { - my_size += 2; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.is_selected != false { - os.write_bool(1, self.is_selected)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> CheckboxDescription { - CheckboxDescription::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "is_selected", - |m: &CheckboxDescription| { &m.is_selected }, - |m: &mut CheckboxDescription| { &mut m.is_selected }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "CheckboxDescription", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static CheckboxDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(CheckboxDescription::new) - } -} - -impl ::protobuf::Clear for CheckboxDescription { - fn clear(&mut self) { - self.is_selected = false; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for CheckboxDescription { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for CheckboxDescription { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct DateDescription { - // message fields - pub date_format: DateFormat, - pub time_format: TimeFormat, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a DateDescription { - fn default() -> &'a DateDescription { - ::default_instance() - } -} - -impl DateDescription { - pub fn new() -> DateDescription { - ::std::default::Default::default() - } - - // .DateFormat date_format = 1; - - - pub fn get_date_format(&self) -> DateFormat { - self.date_format - } - pub fn clear_date_format(&mut self) { - self.date_format = DateFormat::Local; - } - - // Param is passed by value, moved - pub fn set_date_format(&mut self, v: DateFormat) { - self.date_format = v; - } - - // .TimeFormat time_format = 2; - - - pub fn get_time_format(&self) -> TimeFormat { - self.time_format - } - pub fn clear_time_format(&mut self) { - self.time_format = TimeFormat::TwelveHour; - } - - // Param is passed by value, moved - pub fn set_time_format(&mut self, v: TimeFormat) { - self.time_format = v; - } -} - -impl ::protobuf::Message for DateDescription { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.date_format, 1, &mut self.unknown_fields)? - }, - 2 => { - ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.time_format, 2, &mut self.unknown_fields)? - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if self.date_format != DateFormat::Local { - my_size += ::protobuf::rt::enum_size(1, self.date_format); - } - if self.time_format != TimeFormat::TwelveHour { - my_size += ::protobuf::rt::enum_size(2, self.time_format); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.date_format != DateFormat::Local { - os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.date_format))?; - } - if self.time_format != TimeFormat::TwelveHour { - os.write_enum(2, ::protobuf::ProtobufEnum::value(&self.time_format))?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> DateDescription { - DateDescription::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( - "date_format", - |m: &DateDescription| { &m.date_format }, - |m: &mut DateDescription| { &mut m.date_format }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( - "time_format", - |m: &DateDescription| { &m.time_format }, - |m: &mut DateDescription| { &mut m.time_format }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "DateDescription", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static DateDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(DateDescription::new) - } -} - -impl ::protobuf::Clear for DateDescription { - fn clear(&mut self) { - self.date_format = DateFormat::Local; - self.time_format = TimeFormat::TwelveHour; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for DateDescription { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for DateDescription { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct SingleSelectDescription { - // message fields - pub options: ::protobuf::RepeatedField, - pub disable_color: bool, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a SingleSelectDescription { - fn default() -> &'a SingleSelectDescription { - ::default_instance() - } -} - -impl SingleSelectDescription { - pub fn new() -> SingleSelectDescription { - ::std::default::Default::default() - } - - // repeated .SelectOption options = 1; - - - pub fn get_options(&self) -> &[SelectOption] { - &self.options - } - pub fn clear_options(&mut self) { - self.options.clear(); - } - - // Param is passed by value, moved - pub fn set_options(&mut self, v: ::protobuf::RepeatedField) { - self.options = v; - } - - // Mutable pointer to the field. - pub fn mut_options(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.options - } - - // Take field - pub fn take_options(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.options, ::protobuf::RepeatedField::new()) - } - - // bool disable_color = 2; - - - pub fn get_disable_color(&self) -> bool { - self.disable_color - } - pub fn clear_disable_color(&mut self) { - self.disable_color = false; - } - - // Param is passed by value, moved - pub fn set_disable_color(&mut self, v: bool) { - self.disable_color = v; - } -} - -impl ::protobuf::Message for SingleSelectDescription { - fn is_initialized(&self) -> bool { - for v in &self.options { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.options)?; - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.disable_color = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.options { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - if self.disable_color != false { - my_size += 2; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.options { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - if self.disable_color != false { - os.write_bool(2, self.disable_color)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> SingleSelectDescription { - SingleSelectDescription::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "options", - |m: &SingleSelectDescription| { &m.options }, - |m: &mut SingleSelectDescription| { &mut m.options }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "disable_color", - |m: &SingleSelectDescription| { &m.disable_color }, - |m: &mut SingleSelectDescription| { &mut m.disable_color }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "SingleSelectDescription", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static SingleSelectDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(SingleSelectDescription::new) - } -} - -impl ::protobuf::Clear for SingleSelectDescription { - fn clear(&mut self) { - self.options.clear(); - self.disable_color = false; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for SingleSelectDescription { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for SingleSelectDescription { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct MultiSelectDescription { - // message fields - pub options: ::protobuf::RepeatedField, - pub disable_color: bool, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a MultiSelectDescription { - fn default() -> &'a MultiSelectDescription { - ::default_instance() - } -} - -impl MultiSelectDescription { - pub fn new() -> MultiSelectDescription { - ::std::default::Default::default() - } - - // repeated .SelectOption options = 1; - - - pub fn get_options(&self) -> &[SelectOption] { - &self.options - } - pub fn clear_options(&mut self) { - self.options.clear(); - } - - // Param is passed by value, moved - pub fn set_options(&mut self, v: ::protobuf::RepeatedField) { - self.options = v; - } - - // Mutable pointer to the field. - pub fn mut_options(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.options - } - - // Take field - pub fn take_options(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.options, ::protobuf::RepeatedField::new()) - } - - // bool disable_color = 2; - - - pub fn get_disable_color(&self) -> bool { - self.disable_color - } - pub fn clear_disable_color(&mut self) { - self.disable_color = false; - } - - // Param is passed by value, moved - pub fn set_disable_color(&mut self, v: bool) { - self.disable_color = v; - } -} - -impl ::protobuf::Message for MultiSelectDescription { - fn is_initialized(&self) -> bool { - for v in &self.options { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.options)?; - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.disable_color = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.options { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - if self.disable_color != false { - my_size += 2; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.options { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - if self.disable_color != false { - os.write_bool(2, self.disable_color)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> MultiSelectDescription { - MultiSelectDescription::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "options", - |m: &MultiSelectDescription| { &m.options }, - |m: &mut MultiSelectDescription| { &mut m.options }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "disable_color", - |m: &MultiSelectDescription| { &m.disable_color }, - |m: &mut MultiSelectDescription| { &mut m.disable_color }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "MultiSelectDescription", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static MultiSelectDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(MultiSelectDescription::new) - } -} - -impl ::protobuf::Clear for MultiSelectDescription { - fn clear(&mut self) { - self.options.clear(); - self.disable_color = false; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for MultiSelectDescription { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for MultiSelectDescription { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct SelectOption { - // message fields - pub id: ::std::string::String, - pub name: ::std::string::String, - pub color: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a SelectOption { - fn default() -> &'a SelectOption { - ::default_instance() - } -} - -impl SelectOption { - pub fn new() -> SelectOption { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string name = 2; - - - pub fn get_name(&self) -> &str { - &self.name - } - pub fn clear_name(&mut self) { - self.name.clear(); - } - - // Param is passed by value, moved - pub fn set_name(&mut self, v: ::std::string::String) { - self.name = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_name(&mut self) -> &mut ::std::string::String { - &mut self.name - } - - // Take field - pub fn take_name(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.name, ::std::string::String::new()) - } - - // string color = 3; - - - pub fn get_color(&self) -> &str { - &self.color - } - pub fn clear_color(&mut self) { - self.color.clear(); - } - - // Param is passed by value, moved - pub fn set_color(&mut self, v: ::std::string::String) { - self.color = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_color(&mut self) -> &mut ::std::string::String { - &mut self.color - } - - // Take field - pub fn take_color(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.color, ::std::string::String::new()) - } -} - -impl ::protobuf::Message for SelectOption { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.color)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.name.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.name); - } - if !self.color.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.color); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.name.is_empty() { - os.write_string(2, &self.name)?; - } - if !self.color.is_empty() { - os.write_string(3, &self.color)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> SelectOption { - SelectOption::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &SelectOption| { &m.id }, - |m: &mut SelectOption| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "name", - |m: &SelectOption| { &m.name }, - |m: &mut SelectOption| { &mut m.name }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "color", - |m: &SelectOption| { &m.color }, - |m: &mut SelectOption| { &mut m.color }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "SelectOption", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static SelectOption { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(SelectOption::new) - } -} - -impl ::protobuf::Clear for SelectOption { - fn clear(&mut self) { - self.id.clear(); - self.name.clear(); - self.color.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for SelectOption { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for SelectOption { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct NumberDescription { - // message fields - pub money: MoneySymbol, - pub scale: u32, - pub symbol: ::std::string::String, - pub sign_positive: bool, - pub name: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a NumberDescription { - fn default() -> &'a NumberDescription { - ::default_instance() - } -} - -impl NumberDescription { - pub fn new() -> NumberDescription { - ::std::default::Default::default() - } - - // .MoneySymbol money = 1; - - - pub fn get_money(&self) -> MoneySymbol { - self.money - } - pub fn clear_money(&mut self) { - self.money = MoneySymbol::CNY; - } - - // Param is passed by value, moved - pub fn set_money(&mut self, v: MoneySymbol) { - self.money = v; - } - - // uint32 scale = 2; - - - pub fn get_scale(&self) -> u32 { - self.scale - } - pub fn clear_scale(&mut self) { - self.scale = 0; - } - - // Param is passed by value, moved - pub fn set_scale(&mut self, v: u32) { - self.scale = v; - } - - // string symbol = 3; - - - pub fn get_symbol(&self) -> &str { - &self.symbol - } - pub fn clear_symbol(&mut self) { - self.symbol.clear(); - } - - // Param is passed by value, moved - pub fn set_symbol(&mut self, v: ::std::string::String) { - self.symbol = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_symbol(&mut self) -> &mut ::std::string::String { - &mut self.symbol - } - - // Take field - pub fn take_symbol(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.symbol, ::std::string::String::new()) - } - - // bool sign_positive = 4; - - - pub fn get_sign_positive(&self) -> bool { - self.sign_positive - } - pub fn clear_sign_positive(&mut self) { - self.sign_positive = false; - } - - // Param is passed by value, moved - pub fn set_sign_positive(&mut self, v: bool) { - self.sign_positive = v; - } - - // string name = 5; - - - pub fn get_name(&self) -> &str { - &self.name - } - pub fn clear_name(&mut self) { - self.name.clear(); - } - - // Param is passed by value, moved - pub fn set_name(&mut self, v: ::std::string::String) { - self.name = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_name(&mut self) -> &mut ::std::string::String { - &mut self.name - } - - // Take field - pub fn take_name(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.name, ::std::string::String::new()) - } -} - -impl ::protobuf::Message for NumberDescription { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.money, 1, &mut self.unknown_fields)? - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_uint32()?; - self.scale = tmp; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.symbol)?; - }, - 4 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.sign_positive = tmp; - }, - 5 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if self.money != MoneySymbol::CNY { - my_size += ::protobuf::rt::enum_size(1, self.money); - } - if self.scale != 0 { - my_size += ::protobuf::rt::value_size(2, self.scale, ::protobuf::wire_format::WireTypeVarint); - } - if !self.symbol.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.symbol); - } - if self.sign_positive != false { - my_size += 2; - } - if !self.name.is_empty() { - my_size += ::protobuf::rt::string_size(5, &self.name); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.money != MoneySymbol::CNY { - os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.money))?; - } - if self.scale != 0 { - os.write_uint32(2, self.scale)?; - } - if !self.symbol.is_empty() { - os.write_string(3, &self.symbol)?; - } - if self.sign_positive != false { - os.write_bool(4, self.sign_positive)?; - } - if !self.name.is_empty() { - os.write_string(5, &self.name)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> NumberDescription { - NumberDescription::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( - "money", - |m: &NumberDescription| { &m.money }, - |m: &mut NumberDescription| { &mut m.money }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint32>( - "scale", - |m: &NumberDescription| { &m.scale }, - |m: &mut NumberDescription| { &mut m.scale }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "symbol", - |m: &NumberDescription| { &m.symbol }, - |m: &mut NumberDescription| { &mut m.symbol }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "sign_positive", - |m: &NumberDescription| { &m.sign_positive }, - |m: &mut NumberDescription| { &mut m.sign_positive }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "name", - |m: &NumberDescription| { &m.name }, - |m: &mut NumberDescription| { &mut m.name }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "NumberDescription", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static NumberDescription { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(NumberDescription::new) - } -} - -impl ::protobuf::Clear for NumberDescription { - fn clear(&mut self) { - self.money = MoneySymbol::CNY; - self.scale = 0; - self.symbol.clear(); - self.sign_positive = false; - self.name.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for NumberDescription { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for NumberDescription { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum DateFormat { - Local = 0, - US = 1, - ISO = 2, - Friendly = 3, -} - -impl ::protobuf::ProtobufEnum for DateFormat { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(DateFormat::Local), - 1 => ::std::option::Option::Some(DateFormat::US), - 2 => ::std::option::Option::Some(DateFormat::ISO), - 3 => ::std::option::Option::Some(DateFormat::Friendly), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [DateFormat] = &[ - DateFormat::Local, - DateFormat::US, - DateFormat::ISO, - DateFormat::Friendly, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("DateFormat", file_descriptor_proto()) - }) - } -} - -impl ::std::marker::Copy for DateFormat { -} - -impl ::std::default::Default for DateFormat { - fn default() -> Self { - DateFormat::Local - } -} - -impl ::protobuf::reflect::ProtobufValue for DateFormat { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) - } -} - -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum TimeFormat { - TwelveHour = 0, - TwentyFourHour = 1, -} - -impl ::protobuf::ProtobufEnum for TimeFormat { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(TimeFormat::TwelveHour), - 1 => ::std::option::Option::Some(TimeFormat::TwentyFourHour), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [TimeFormat] = &[ - TimeFormat::TwelveHour, - TimeFormat::TwentyFourHour, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("TimeFormat", file_descriptor_proto()) - }) - } -} - -impl ::std::marker::Copy for TimeFormat { -} - -impl ::std::default::Default for TimeFormat { - fn default() -> Self { - TimeFormat::TwelveHour - } -} - -impl ::protobuf::reflect::ProtobufValue for TimeFormat { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) - } -} - -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum MoneySymbol { - CNY = 0, - EUR = 1, - USD = 2, -} - -impl ::protobuf::ProtobufEnum for MoneySymbol { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(MoneySymbol::CNY), - 1 => ::std::option::Option::Some(MoneySymbol::EUR), - 2 => ::std::option::Option::Some(MoneySymbol::USD), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [MoneySymbol] = &[ - MoneySymbol::CNY, - MoneySymbol::EUR, - MoneySymbol::USD, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("MoneySymbol", file_descriptor_proto()) - }) - } -} - -impl ::std::marker::Copy for MoneySymbol { -} - -impl ::std::default::Default for MoneySymbol { - fn default() -> Self { - MoneySymbol::CNY - } -} - -impl ::protobuf::reflect::ProtobufValue for MoneySymbol { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) - } -} - -static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x12type_options.proto\"-\n\x13RichTextDescription\x12\x16\n\x06format\ - \x18\x01\x20\x01(\tR\x06format\"6\n\x13CheckboxDescription\x12\x1f\n\x0b\ - is_selected\x18\x01\x20\x01(\x08R\nisSelected\"m\n\x0fDateDescription\ - \x12,\n\x0bdate_format\x18\x01\x20\x01(\x0e2\x0b.DateFormatR\ndateFormat\ - \x12,\n\x0btime_format\x18\x02\x20\x01(\x0e2\x0b.TimeFormatR\ntimeFormat\ - \"g\n\x17SingleSelectDescription\x12'\n\x07options\x18\x01\x20\x03(\x0b2\ - \r.SelectOptionR\x07options\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\ - \x0cdisableColor\"f\n\x16MultiSelectDescription\x12'\n\x07options\x18\ - \x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x12#\n\rdisable_color\x18\ - \x02\x20\x01(\x08R\x0cdisableColor\"H\n\x0cSelectOption\x12\x0e\n\x02id\ - \x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\ - \x12\x14\n\x05color\x18\x03\x20\x01(\tR\x05color\"\x9e\x01\n\x11NumberDe\ - scription\x12\"\n\x05money\x18\x01\x20\x01(\x0e2\x0c.MoneySymbolR\x05mon\ - ey\x12\x14\n\x05scale\x18\x02\x20\x01(\rR\x05scale\x12\x16\n\x06symbol\ - \x18\x03\x20\x01(\tR\x06symbol\x12#\n\rsign_positive\x18\x04\x20\x01(\ - \x08R\x0csignPositive\x12\x12\n\x04name\x18\x05\x20\x01(\tR\x04name*6\n\ - \nDateFormat\x12\t\n\x05Local\x10\0\x12\x06\n\x02US\x10\x01\x12\x07\n\ - \x03ISO\x10\x02\x12\x0c\n\x08Friendly\x10\x03*0\n\nTimeFormat\x12\x0e\n\ - \nTwelveHour\x10\0\x12\x12\n\x0eTwentyFourHour\x10\x01*(\n\x0bMoneySymbo\ - l\x12\x07\n\x03CNY\x10\0\x12\x07\n\x03EUR\x10\x01\x12\x07\n\x03USD\x10\ - \x02b\x06proto3\ -"; - -static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; - -fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { - ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() -} - -pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { - file_descriptor_proto_lazy.get(|| { - parse_descriptor_proto() - }) -} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/checkbox_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/checkbox_description.proto new file mode 100644 index 0000000000..7c14ebc075 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/checkbox_description.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message CheckboxDescription { + bool is_selected = 1; +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/date_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/date_description.proto new file mode 100644 index 0000000000..9fe4c4acfd --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/date_description.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +message DateDescription { + DateFormat date_format = 1; + TimeFormat time_format = 2; +} +enum DateFormat { + Local = 0; + US = 1; + ISO = 2; + Friendly = 3; +} +enum TimeFormat { + TwelveHour = 0; + TwentyFourHour = 1; +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto new file mode 100644 index 0000000000..83ab8b7220 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +message NumberDescription { + MoneySymbol money = 1; + uint32 scale = 2; + string symbol = 3; + bool sign_positive = 4; + string name = 5; +} +enum MoneySymbol { + CNY = 0; + EUR = 1; + USD = 2; +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_description.proto new file mode 100644 index 0000000000..7f3ee25661 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_description.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +message SingleSelectDescription { + repeated SelectOption options = 1; + bool disable_color = 2; +} +message MultiSelectDescription { + repeated SelectOption options = 1; + bool disable_color = 2; +} +message SelectOption { + string id = 1; + string name = 2; + string color = 3; +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/text_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/text_description.proto new file mode 100644 index 0000000000..c4ee8f8de6 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/text_description.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message RichTextDescription { + string format = 1; +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/type_options.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/type_options.proto deleted file mode 100644 index 170035085c..0000000000 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/type_options.proto +++ /dev/null @@ -1,47 +0,0 @@ -syntax = "proto3"; - -message RichTextDescription { - string format = 1; -} -message CheckboxDescription { - bool is_selected = 1; -} -message DateDescription { - DateFormat date_format = 1; - TimeFormat time_format = 2; -} -message SingleSelectDescription { - repeated SelectOption options = 1; - bool disable_color = 2; -} -message MultiSelectDescription { - repeated SelectOption options = 1; - bool disable_color = 2; -} -message SelectOption { - string id = 1; - string name = 2; - string color = 3; -} -message NumberDescription { - MoneySymbol money = 1; - uint32 scale = 2; - string symbol = 3; - bool sign_positive = 4; - string name = 5; -} -enum DateFormat { - Local = 0; - US = 1; - ISO = 2; - Friendly = 3; -} -enum TimeFormat { - TwelveHour = 0; - TwentyFourHour = 1; -} -enum MoneySymbol { - CNY = 0; - EUR = 1; - USD = 2; -} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs b/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs new file mode 100644 index 0000000000..a472dec8c5 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs @@ -0,0 +1,137 @@ +use crate::services::cell::*; +use crate::services::field::TypeOptionsBuilder; +use flowy_grid_data_model::entities::FieldType; + +// Text +#[derive(Default)] +pub struct RichTextTypeOptionsBuilder(RichTextDescription); + +impl TypeOptionsBuilder for RichTextTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + +// Number +#[derive(Default)] +pub struct NumberTypeOptionsBuilder(NumberDescription); + +impl NumberTypeOptionsBuilder { + pub fn name(mut self, name: &str) -> Self { + self.0.name = name.to_string(); + self + } + + pub fn set_money_symbol(mut self, money_symbol: MoneySymbol) -> Self { + self.0.set_money_symbol(money_symbol); + self + } + + pub fn scale(mut self, scale: u32) -> Self { + self.0.scale = scale; + self + } + + pub fn positive(mut self, positive: bool) -> Self { + self.0.sign_positive = positive; + self + } +} + +impl TypeOptionsBuilder for NumberTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + +// Date +#[derive(Default)] +pub struct DateTypeOptionsBuilder(DateDescription); +impl DateTypeOptionsBuilder { + pub fn date_format(mut self, date_format: DateFormat) -> Self { + self.0.date_format = date_format; + self + } + + pub fn time_format(mut self, time_format: TimeFormat) -> Self { + self.0.time_format = time_format; + self + } +} +impl TypeOptionsBuilder for DateTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + +// Single Select +#[derive(Default)] +pub struct SingleSelectTypeOptionsBuilder(SingleSelectDescription); + +impl SingleSelectTypeOptionsBuilder { + pub fn option(mut self, opt: SelectOption) -> Self { + self.0.options.push(opt); + self + } +} +impl TypeOptionsBuilder for SingleSelectTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + +// Multi Select +#[derive(Default)] +pub struct MultiSelectTypeOptionsBuilder(MultiSelectDescription); + +impl MultiSelectTypeOptionsBuilder { + pub fn option(mut self, opt: SelectOption) -> Self { + self.0.options.push(opt); + self + } +} + +impl TypeOptionsBuilder for MultiSelectTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} + +// Checkbox +#[derive(Default)] +pub struct CheckboxTypeOptionsBuilder(CheckboxDescription); +impl CheckboxTypeOptionsBuilder { + pub fn set_selected(mut self, is_selected: bool) -> Self { + self.0.is_selected = is_selected; + self + } +} +impl TypeOptionsBuilder for CheckboxTypeOptionsBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn build(&self) -> String { + self.0.clone().into() + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs new file mode 100644 index 0000000000..f6f3603604 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs @@ -0,0 +1,40 @@ +use crate::impl_from_and_to_type_option; +use crate::services::row::StringifyCellData; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{Field, FieldType}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] +pub struct CheckboxDescription { + #[pb(index = 1)] + pub is_selected: bool, +} +impl_from_and_to_type_option!(CheckboxDescription, FieldType::Checkbox); + +impl StringifyCellData for CheckboxDescription { + fn str_from_cell_data(&self, data: String) -> String { + data + } + + fn str_to_cell_data(&self, s: &str) -> Result { + let s = match string_to_bool(s) { + true => "1", + false => "0", + }; + Ok(s.to_owned()) + } +} + +fn string_to_bool(bool_str: &str) -> bool { + let lower_case_str: &str = &bool_str.to_lowercase(); + match lower_case_str { + "1" => true, + "true" => true, + "yes" => true, + "0" => false, + "false" => false, + "no" => false, + _ => false, + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs new file mode 100644 index 0000000000..09cb04f163 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs @@ -0,0 +1,145 @@ +use crate::impl_from_and_to_type_option; +use crate::services::row::StringifyCellData; +use crate::services::util::*; +use chrono::format::strftime::StrftimeItems; +use chrono::NaiveDateTime; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{Field, FieldType}; +use serde::{Deserialize, Serialize}; + +// Date +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] +pub struct DateDescription { + #[pb(index = 1)] + pub date_format: DateFormat, + + #[pb(index = 2)] + pub time_format: TimeFormat, +} +impl_from_and_to_type_option!(DateDescription, FieldType::DateTime); + +impl DateDescription { + fn date_time_format_str(&self) -> String { + format!("{} {}", self.date_format.format_str(), self.time_format.format_str()) + } + + #[allow(dead_code)] + fn today_from_timestamp(&self, timestamp: i64) -> String { + let native = chrono::NaiveDateTime::from_timestamp(timestamp, 0); + self.today_from_native(native) + } + + fn today_from_native(&self, naive: chrono::NaiveDateTime) -> String { + let utc: chrono::DateTime = chrono::DateTime::from_utc(naive, chrono::Utc); + let local: chrono::DateTime = chrono::DateTime::from(utc); + + let fmt_str = self.date_time_format_str(); + let output = format!("{}", local.format_with_items(StrftimeItems::new(&fmt_str))); + output + } +} + +impl StringifyCellData for DateDescription { + fn str_from_cell_data(&self, data: String) -> String { + match data.parse::() { + Ok(timestamp) => { + let native = NaiveDateTime::from_timestamp(timestamp, 0); + self.today_from_native(native) + } + Err(e) => { + tracing::debug!("DateDescription format {} fail. error: {:?}", data, e); + String::new() + } + } + } + + fn str_to_cell_data(&self, s: &str) -> Result { + let timestamp = s + .parse::() + .map_err(|e| FlowyError::internal().context(format!("Parse {} to i64 failed: {}", s, e)))?; + Ok(format!("{}", timestamp)) + } +} + +#[derive(Clone, Debug, Copy, Serialize, Deserialize, ProtoBuf_Enum)] +pub enum DateFormat { + Local = 0, + US = 1, + ISO = 2, + Friendly = 3, +} +impl std::default::Default for DateFormat { + fn default() -> Self { + DateFormat::Friendly + } +} + +impl std::convert::From for DateFormat { + fn from(value: i32) -> Self { + match value { + 0 => DateFormat::Local, + 1 => DateFormat::US, + 2 => DateFormat::ISO, + 3 => DateFormat::Friendly, + _ => { + tracing::error!("Unsupported date format, fallback to friendly"); + DateFormat::Friendly + } + } + } +} + +impl DateFormat { + pub fn value(&self) -> i32 { + *self as i32 + } + // https://docs.rs/chrono/0.4.19/chrono/format/strftime/index.html + pub fn format_str(&self) -> &'static str { + match self { + DateFormat::Local => "%Y/%m/%d", + DateFormat::US => "%Y/%m/%d", + DateFormat::ISO => "%Y-%m-%d", + DateFormat::Friendly => "%b %d,%Y", + } + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize, ProtoBuf_Enum)] +pub enum TimeFormat { + TwelveHour = 0, + TwentyFourHour = 1, +} + +impl std::convert::From for TimeFormat { + fn from(value: i32) -> Self { + match value { + 0 => TimeFormat::TwelveHour, + 1 => TimeFormat::TwentyFourHour, + _ => { + tracing::error!("Unsupported time format, fallback to TwentyFourHour"); + TimeFormat::TwentyFourHour + } + } + } +} + +impl TimeFormat { + pub fn value(&self) -> i32 { + *self as i32 + } + + // https://docs.rs/chrono/0.4.19/chrono/format/strftime/index.html + pub fn format_str(&self) -> &'static str { + match self { + TimeFormat::TwelveHour => "%r", + TimeFormat::TwentyFourHour => "%R", + } + } +} + +impl std::default::Default for TimeFormat { + fn default() -> Self { + TimeFormat::TwentyFourHour + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/mod.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/mod.rs new file mode 100644 index 0000000000..faadd45f8c --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/mod.rs @@ -0,0 +1,11 @@ +mod checkbox_description; +mod date_description; +mod number_description; +mod selection_description; +mod text_description; + +pub use checkbox_description::*; +pub use date_description::*; +pub use number_description::*; +pub use selection_description::*; +pub use text_description::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs new file mode 100644 index 0000000000..569d3c8c95 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs @@ -0,0 +1,150 @@ +use crate::impl_from_and_to_type_option; +use crate::services::row::StringifyCellData; +use crate::services::util::*; +use chrono::format::strftime::StrftimeItems; +use chrono::NaiveDateTime; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{Field, FieldType}; +use rust_decimal::Decimal; +use rusty_money::{ + iso::{Currency, CNY, EUR, USD}, + Money, +}; +use serde::{Deserialize, Serialize}; +use std::str::FromStr; +use strum_macros::EnumIter; + +// Number +#[derive(Clone, Debug, Serialize, Deserialize, ProtoBuf)] +pub struct NumberDescription { + #[pb(index = 1)] + pub money: MoneySymbol, + + #[pb(index = 2)] + pub scale: u32, + + #[pb(index = 3)] + pub symbol: String, + + #[pb(index = 4)] + pub sign_positive: bool, + + #[pb(index = 5)] + pub name: String, +} +impl_from_and_to_type_option!(NumberDescription, FieldType::Number); + +impl std::default::Default for NumberDescription { + fn default() -> Self { + let money = MoneySymbol::default(); + let symbol = money.symbol_str(); + NumberDescription { + money, + scale: 0, + symbol, + sign_positive: true, + name: "Number".to_string(), + } + } +} + +impl NumberDescription { + pub fn set_money_symbol(&mut self, money_symbol: MoneySymbol) { + self.money = money_symbol; + self.symbol = money_symbol.symbol_str(); + } + + fn money_from_str(&self, s: &str) -> Option { + match Decimal::from_str(s) { + Ok(mut decimal) => { + match decimal.set_scale(self.scale) { + Ok(_) => {} + Err(e) => { + tracing::error!("Set decimal scale failed: {:?}", e); + } + } + decimal.set_sign_positive(self.sign_positive); + Some(self.money.with_decimal(decimal).to_string()) + } + Err(e) => { + tracing::error!("Parser money from {} failed: {:?}", s, e); + None + } + } + } +} + +impl StringifyCellData for NumberDescription { + fn str_from_cell_data(&self, data: String) -> String { + match self.money_from_str(&data) { + Some(money_str) => money_str, + None => String::default(), + } + } + + fn str_to_cell_data(&self, s: &str) -> Result { + let strip_symbol_money = strip_money_symbol(s); + let decimal = Decimal::from_str(&strip_symbol_money).map_err(|err| FlowyError::internal().context(err))?; + Ok(decimal.to_string()) + } +} + +#[derive(Clone, Copy, Debug, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] +pub enum MoneySymbol { + CNY = 0, + EUR = 1, + USD = 2, +} + +impl std::default::Default for MoneySymbol { + fn default() -> Self { + MoneySymbol::USD + } +} + +impl MoneySymbol { + // Currency list https://docs.rs/rusty-money/0.4.0/rusty_money/iso/index.html + pub fn from_symbol_str(s: &str) -> MoneySymbol { + match s { + "CNY" => MoneySymbol::CNY, + "EUR" => MoneySymbol::EUR, + "USD" => MoneySymbol::USD, + _ => MoneySymbol::CNY, + } + } + + pub fn from_money(money: &rusty_money::Money) -> MoneySymbol { + MoneySymbol::from_symbol_str(&money.currency().symbol.to_string()) + } + + pub fn currency(&self) -> &'static Currency { + match self { + MoneySymbol::CNY => CNY, + MoneySymbol::EUR => EUR, + MoneySymbol::USD => USD, + } + } + + // string_to_money("¥18,443").unwrap(); + // string_to_money("$18,443").unwrap(); + // string_to_money("€18,443").unwrap(); + pub fn code(&self) -> String { + self.currency().iso_alpha_code.to_string() + } + + pub fn symbol_str(&self) -> String { + self.currency().symbol.to_string() + } + + pub fn zero(&self) -> Money { + let mut decimal = Decimal::new(0, 0); + decimal.set_sign_positive(true); + self.with_decimal(decimal) + } + + pub fn with_decimal(&self, decimal: Decimal) -> Money { + let money = rusty_money::Money::from_decimal(decimal, self.currency()); + money + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs new file mode 100644 index 0000000000..872210b4b3 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs @@ -0,0 +1,70 @@ +use crate::impl_from_and_to_type_option; +use crate::services::row::StringifyCellData; +use crate::services::util::*; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{Field, FieldType}; +use serde::{Deserialize, Serialize}; + +// Single select +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] +pub struct SingleSelectDescription { + #[pb(index = 1)] + pub options: Vec, + + #[pb(index = 2)] + pub disable_color: bool, +} +impl_from_and_to_type_option!(SingleSelectDescription, FieldType::SingleSelect); + +impl StringifyCellData for SingleSelectDescription { + fn str_from_cell_data(&self, data: String) -> String { + data + } + + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(s.to_owned()) + } +} + +// Multiple select +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] +pub struct MultiSelectDescription { + #[pb(index = 1)] + pub options: Vec, + + #[pb(index = 2)] + pub disable_color: bool, +} +impl_from_and_to_type_option!(MultiSelectDescription, FieldType::MultiSelect); +impl StringifyCellData for MultiSelectDescription { + fn str_from_cell_data(&self, data: String) -> String { + data + } + + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(s.to_owned()) + } +} + +#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] +pub struct SelectOption { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub name: String, + + #[pb(index = 3)] + pub color: String, +} + +impl SelectOption { + pub fn new(name: &str) -> Self { + SelectOption { + id: uuid(), + name: name.to_owned(), + color: "".to_string(), + } + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs new file mode 100644 index 0000000000..228eed240d --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs @@ -0,0 +1,24 @@ +use crate::impl_from_and_to_type_option; +use crate::services::row::StringifyCellData; +use crate::services::util::*; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{Field, FieldType}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] +pub struct RichTextDescription { + #[pb(index = 1)] + pub format: String, +} +impl_from_and_to_type_option!(RichTextDescription, FieldType::RichText); + +impl StringifyCellData for RichTextDescription { + fn str_from_cell_data(&self, data: String) -> String { + data + } + + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(s.to_owned()) + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs b/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs new file mode 100644 index 0000000000..0c28db7789 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs @@ -0,0 +1,5 @@ +mod builder; +mod description; + +pub use builder::*; +pub use description::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index 8b75389ce4..034e7c34fb 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -1,7 +1,3 @@ -use crate::services::field::{ - CheckboxDescription, DateDescription, DateFormat, MoneySymbol, MultiSelectDescription, NumberDescription, - RichTextDescription, SelectOption, SingleSelectDescription, TimeFormat, -}; use flowy_grid_data_model::entities::{Field, FieldType}; pub struct FieldBuilder { @@ -61,157 +57,3 @@ pub trait TypeOptionsBuilder { fn field_type(&self) -> FieldType; fn build(&self) -> String; } - -// Text -pub struct RichTextTypeOptionsBuilder(RichTextDescription); - -impl RichTextTypeOptionsBuilder { - pub fn new() -> Self { - Self(RichTextDescription::default()) - } -} - -impl TypeOptionsBuilder for RichTextTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} - -// Number -pub struct NumberTypeOptionsBuilder(NumberDescription); - -impl NumberTypeOptionsBuilder { - pub fn new() -> Self { - Self(NumberDescription::default()) - } - - pub fn name(mut self, name: &str) -> Self { - self.0.name = name.to_string(); - self - } - - pub fn set_money_symbol(mut self, money_symbol: MoneySymbol) -> Self { - self.0.set_money_symbol(money_symbol); - self - } - - pub fn scale(mut self, scale: u32) -> Self { - self.0.scale = scale; - self - } - - pub fn positive(mut self, positive: bool) -> Self { - self.0.sign_positive = positive; - self - } -} - -impl TypeOptionsBuilder for NumberTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} - -// Date -pub struct DateTypeOptionsBuilder(DateDescription); -impl DateTypeOptionsBuilder { - pub fn new() -> Self { - Self(DateDescription::default()) - } - - pub fn date_format(mut self, date_format: DateFormat) -> Self { - self.0.date_format = date_format; - self - } - - pub fn time_format(mut self, time_format: TimeFormat) -> Self { - self.0.time_format = time_format; - self - } -} -impl TypeOptionsBuilder for DateTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} - -// Single Select -pub struct SingleSelectTypeOptionsBuilder(SingleSelectDescription); - -impl SingleSelectTypeOptionsBuilder { - pub fn new() -> Self { - Self(SingleSelectDescription::default()) - } - - pub fn option(mut self, opt: SelectOption) -> Self { - self.0.options.push(opt); - self - } -} -impl TypeOptionsBuilder for SingleSelectTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} - -// Multi Select -pub struct MultiSelectTypeOptionsBuilder(MultiSelectDescription); - -impl MultiSelectTypeOptionsBuilder { - pub fn new() -> Self { - Self(MultiSelectDescription::default()) - } - - pub fn option(mut self, opt: SelectOption) -> Self { - self.0.options.push(opt); - self - } -} - -impl TypeOptionsBuilder for MultiSelectTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} - -// Checkbox -pub struct CheckboxTypeOptionsBuilder(CheckboxDescription); -impl CheckboxTypeOptionsBuilder { - pub fn new() -> Self { - Self(CheckboxDescription::default()) - } - - pub fn set_selected(mut self, is_selected: bool) -> Self { - self.0.is_selected = is_selected; - self - } -} -impl TypeOptionsBuilder for CheckboxTypeOptionsBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn build(&self) -> String { - self.0.clone().into() - } -} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs index 61b5889e68..50d069cf9b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs @@ -1,5 +1,3 @@ mod field_builder; -mod type_options; pub use field_builder::*; -pub use type_options::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs deleted file mode 100644 index 080e3aaa60..0000000000 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs +++ /dev/null @@ -1,390 +0,0 @@ -#![allow(clippy::upper_case_acronyms)] -use crate::impl_from_and_to_type_option; -use crate::services::row::StringifyCellData; -use crate::services::util::*; - -use chrono::format::strftime::StrftimeItems; -use chrono::NaiveDateTime; -use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; -use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Field, FieldType}; -use rust_decimal::Decimal; -use rusty_money::{ - iso::{Currency, CNY, EUR, USD}, - Money, -}; -use serde::{Deserialize, Serialize}; -use std::str::FromStr; -use strum_macros::EnumIter; - -#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] -pub struct RichTextDescription { - #[pb(index = 1)] - pub format: String, -} -impl_from_and_to_type_option!(RichTextDescription, FieldType::RichText); - -impl StringifyCellData for RichTextDescription { - fn str_from_cell_data(&self, data: String) -> String { - data - } - - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(s.to_owned()) - } -} - -// Checkbox -#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] -pub struct CheckboxDescription { - #[pb(index = 1)] - pub is_selected: bool, -} -impl_from_and_to_type_option!(CheckboxDescription, FieldType::Checkbox); - -impl StringifyCellData for CheckboxDescription { - fn str_from_cell_data(&self, data: String) -> String { - data - } - - fn str_to_cell_data(&self, s: &str) -> Result { - let s = match string_to_bool(s) { - true => "1", - false => "0", - }; - Ok(s.to_owned()) - } -} - -// Date -#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] -pub struct DateDescription { - #[pb(index = 1)] - pub date_format: DateFormat, - - #[pb(index = 2)] - pub time_format: TimeFormat, -} -impl_from_and_to_type_option!(DateDescription, FieldType::DateTime); - -impl DateDescription { - fn date_time_format_str(&self) -> String { - format!("{} {}", self.date_format.format_str(), self.time_format.format_str()) - } - - #[allow(dead_code)] - fn today_from_timestamp(&self, timestamp: i64) -> String { - let native = chrono::NaiveDateTime::from_timestamp(timestamp, 0); - self.today_from_native(native) - } - - fn today_from_native(&self, naive: chrono::NaiveDateTime) -> String { - let utc: chrono::DateTime = chrono::DateTime::from_utc(naive, chrono::Utc); - let local: chrono::DateTime = chrono::DateTime::from(utc); - - let fmt_str = self.date_time_format_str(); - let output = format!("{}", local.format_with_items(StrftimeItems::new(&fmt_str))); - output - } -} - -impl StringifyCellData for DateDescription { - fn str_from_cell_data(&self, data: String) -> String { - match data.parse::() { - Ok(timestamp) => { - let native = NaiveDateTime::from_timestamp(timestamp, 0); - self.today_from_native(native) - } - Err(e) => { - tracing::debug!("DateDescription format {} fail. error: {:?}", data, e); - String::new() - } - } - } - - fn str_to_cell_data(&self, s: &str) -> Result { - let timestamp = s - .parse::() - .map_err(|e| FlowyError::internal().context(format!("Parse {} to i64 failed: {}", s, e)))?; - Ok(format!("{}", timestamp)) - } -} - -#[derive(Clone, Debug, Copy, Serialize, Deserialize, ProtoBuf_Enum)] -pub enum DateFormat { - Local = 0, - US = 1, - ISO = 2, - Friendly = 3, -} -impl std::default::Default for DateFormat { - fn default() -> Self { - DateFormat::Friendly - } -} - -impl std::convert::From for DateFormat { - fn from(value: i32) -> Self { - match value { - 0 => DateFormat::Local, - 1 => DateFormat::US, - 2 => DateFormat::ISO, - 3 => DateFormat::Friendly, - _ => { - tracing::error!("Unsupported date format, fallback to friendly"); - DateFormat::Friendly - } - } - } -} - -impl DateFormat { - pub fn value(&self) -> i32 { - *self as i32 - } - // https://docs.rs/chrono/0.4.19/chrono/format/strftime/index.html - pub fn format_str(&self) -> &'static str { - match self { - DateFormat::Local => "%Y/%m/%d", - DateFormat::US => "%Y/%m/%d", - DateFormat::ISO => "%Y-%m-%d", - DateFormat::Friendly => "%b %d,%Y", - } - } -} - -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize, ProtoBuf_Enum)] -pub enum TimeFormat { - TwelveHour = 0, - TwentyFourHour = 1, -} - -impl std::convert::From for TimeFormat { - fn from(value: i32) -> Self { - match value { - 0 => TimeFormat::TwelveHour, - 1 => TimeFormat::TwentyFourHour, - _ => { - tracing::error!("Unsupported time format, fallback to TwentyFourHour"); - TimeFormat::TwentyFourHour - } - } - } -} - -impl TimeFormat { - pub fn value(&self) -> i32 { - *self as i32 - } - - // https://docs.rs/chrono/0.4.19/chrono/format/strftime/index.html - pub fn format_str(&self) -> &'static str { - match self { - TimeFormat::TwelveHour => "%r", - TimeFormat::TwentyFourHour => "%R", - } - } -} - -impl std::default::Default for TimeFormat { - fn default() -> Self { - TimeFormat::TwentyFourHour - } -} - -// Single select -#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] -pub struct SingleSelectDescription { - #[pb(index = 1)] - pub options: Vec, - - #[pb(index = 2)] - pub disable_color: bool, -} -impl_from_and_to_type_option!(SingleSelectDescription, FieldType::SingleSelect); - -impl StringifyCellData for SingleSelectDescription { - fn str_from_cell_data(&self, data: String) -> String { - data - } - - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(s.to_owned()) - } -} - -// Multiple select -#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] -pub struct MultiSelectDescription { - #[pb(index = 1)] - pub options: Vec, - - #[pb(index = 2)] - pub disable_color: bool, -} -impl_from_and_to_type_option!(MultiSelectDescription, FieldType::MultiSelect); -impl StringifyCellData for MultiSelectDescription { - fn str_from_cell_data(&self, data: String) -> String { - data - } - - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(s.to_owned()) - } -} - -#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] -pub struct SelectOption { - #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub name: String, - - #[pb(index = 3)] - pub color: String, -} - -impl SelectOption { - pub fn new(name: &str) -> Self { - SelectOption { - id: uuid(), - name: name.to_owned(), - color: "".to_string(), - } - } -} - -// Number -#[derive(Clone, Debug, Serialize, Deserialize, ProtoBuf)] -pub struct NumberDescription { - #[pb(index = 1)] - pub money: MoneySymbol, - - #[pb(index = 2)] - pub scale: u32, - - #[pb(index = 3)] - pub symbol: String, - - #[pb(index = 4)] - pub sign_positive: bool, - - #[pb(index = 5)] - pub name: String, -} -impl_from_and_to_type_option!(NumberDescription, FieldType::Number); - -impl std::default::Default for NumberDescription { - fn default() -> Self { - let money = MoneySymbol::default(); - let symbol = money.symbol_str(); - NumberDescription { - money, - scale: 0, - symbol, - sign_positive: true, - name: "Number".to_string(), - } - } -} - -impl NumberDescription { - pub fn set_money_symbol(&mut self, money_symbol: MoneySymbol) { - self.money = money_symbol; - self.symbol = money_symbol.symbol_str(); - } - - fn money_from_str(&self, s: &str) -> Option { - match Decimal::from_str(s) { - Ok(mut decimal) => { - match decimal.set_scale(self.scale) { - Ok(_) => {} - Err(e) => { - tracing::error!("Set decimal scale failed: {:?}", e); - } - } - decimal.set_sign_positive(self.sign_positive); - Some(self.money.with_decimal(decimal).to_string()) - } - Err(e) => { - tracing::error!("Parser money from {} failed: {:?}", s, e); - None - } - } - } -} - -impl StringifyCellData for NumberDescription { - fn str_from_cell_data(&self, data: String) -> String { - match self.money_from_str(&data) { - Some(money_str) => money_str, - None => String::default(), - } - } - - fn str_to_cell_data(&self, s: &str) -> Result { - let strip_symbol_money = strip_money_symbol(s); - let decimal = Decimal::from_str(&strip_symbol_money).map_err(|err| FlowyError::internal().context(err))?; - Ok(decimal.to_string()) - } -} - -#[derive(Clone, Copy, Debug, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] -pub enum MoneySymbol { - CNY = 0, - EUR = 1, - USD = 2, -} - -impl std::default::Default for MoneySymbol { - fn default() -> Self { - MoneySymbol::USD - } -} - -impl MoneySymbol { - // Currency list https://docs.rs/rusty-money/0.4.0/rusty_money/iso/index.html - pub fn from_symbol_str(s: &str) -> MoneySymbol { - match s { - "CNY" => MoneySymbol::CNY, - "EUR" => MoneySymbol::EUR, - "USD" => MoneySymbol::USD, - _ => MoneySymbol::CNY, - } - } - - pub fn from_money(money: &rusty_money::Money) -> MoneySymbol { - MoneySymbol::from_symbol_str(&money.currency().symbol.to_string()) - } - - pub fn currency(&self) -> &'static Currency { - match self { - MoneySymbol::CNY => CNY, - MoneySymbol::EUR => EUR, - MoneySymbol::USD => USD, - } - } - - // string_to_money("¥18,443").unwrap(); - // string_to_money("$18,443").unwrap(); - // string_to_money("€18,443").unwrap(); - pub fn code(&self) -> String { - self.currency().iso_alpha_code.to_string() - } - - pub fn symbol_str(&self) -> String { - self.currency().symbol.to_string() - } - - pub fn zero(&self) -> Money { - let mut decimal = Decimal::new(0, 0); - decimal.set_sign_positive(true); - self.with_decimal(decimal) - } - - pub fn with_decimal(&self, decimal: Decimal) -> Money { - let money = rusty_money::Money::from_decimal(decimal, self.currency()); - money - } -} 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 63defcf76b..c31b1734b3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,17 +1,20 @@ use crate::manager::GridUser; -use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; - use crate::services::grid_meta_editor::GridBlockMetaEditorManager; +use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use bytes::Bytes; -use dashmap::DashMap; use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Field, FieldChangeset, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, RepeatedRowOrder, Row, + CellMetaChangeset, Field, FieldChangeset, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, + RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, }; +use std::collections::HashMap; +use crate::services::row::{ + make_row_by_row_id, make_rows, row_meta_from_context, CreateRowContext, CreateRowContextBuilder, +}; use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; @@ -73,44 +76,83 @@ impl ClientGridEditor { Ok(()) } - pub async fn update_block(&self, change: GridBlockChangeset) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.update_block(change)?)).await?; + pub async fn update_block(&self, changeset: GridBlockChangeset) -> FlowyResult<()> { + let _ = self.modify(|grid| Ok(grid.update_block(changeset)?)).await?; Ok(()) } pub async fn create_row(&self) -> FlowyResult<()> { let fields = self.grid_meta_pad.read().await.get_fields(None)?; - let grid_block = match self.grid_meta_pad.read().await.get_blocks().last() { - None => Err(FlowyError::internal().context("There is no grid block in this grid")), - Some(grid_block) => Ok(grid_block.clone()), - }?; - - let row_count = self.block_meta_manager.create_row(fields, &grid_block).await?; - let change = GridBlockChangeset::from_row_count(&grid_block.id, row_count); - let _ = self.update_block(change).await?; + let block_id = self.last_block_id().await?; + let row = row_meta_from_context(&block_id, CreateRowContextBuilder::new(&fields).build()); + let row_count = self.block_meta_manager.create_row(row).await?; + let changeset = GridBlockChangeset::from_row_count(&block_id, row_count); + let _ = self.update_block(changeset).await?; Ok(()) } - pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult> { - let fields = self.grid_meta_pad.read().await.get_fields(None)?; - let rows = self.block_meta_manager.get_rows(fields, row_orders).await?; - Ok(rows) - } + pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult<()> { + let block_id = self.last_block_id().await?; + let mut rows_by_block_id: HashMap> = HashMap::new(); - pub async fn get_all_rows(&self) -> FlowyResult> { - let fields = self.grid_meta_pad.read().await.get_fields(None)?; - let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); - self.block_meta_manager.get_all_rows(grid_blocks, fields).await - } - - pub async fn delete_rows(&self, row_orders: Option) -> FlowyResult<()> { - let row_counts = self.block_meta_manager.delete_rows(row_orders).await?; - for (block_id, row_count) in row_counts { - let _ = self - .update_block(GridBlockChangeset::from_row_count(&block_id, row_count)) - .await?; + for ctx in contexts { + let row_meta = row_meta_from_context(&block_id, ctx); + rows_by_block_id + .entry(block_id.clone()) + .or_insert(Vec::new()) + .push(row_meta); } + let changesets = self.block_meta_manager.insert_row(rows_by_block_id).await?; + for changeset in changesets { + let _ = self.update_block(changeset).await?; + } + Ok(()) + } + pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { + self.block_meta_manager.update_row(changeset).await + } + + pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> { + let row_changeset: RowMetaChangeset = changeset.into(); + self.update_row(row_changeset).await + } + + pub async fn get_rows(&self, row_orders: Option) -> FlowyResult> { + let row_metas = self.get_row_metas(&row_orders).await?; + let fields = self.grid_meta_pad.read().await.get_fields(None)?; + match row_orders { + None => Ok(make_rows(&fields, row_metas)), + Some(row_orders) => { + let mut row_map: HashMap = make_row_by_row_id(&fields, row_metas); + let rows = row_orders + .iter() + .flat_map(|row_order| row_map.remove(&row_order.row_id)) + .collect::>(); + Ok(rows) + } + } + } + + pub async fn get_row_metas(&self, row_orders: &Option) -> FlowyResult> { + match row_orders { + None => { + let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); + let row_metas = self.block_meta_manager.get_all_rows(grid_blocks).await?; + Ok(row_metas) + } + Some(row_orders) => { + let row_metas = self.block_meta_manager.get_rows(row_orders).await?; + Ok(row_metas) + } + } + } + + pub async fn delete_rows(&self, row_ids: Vec) -> FlowyResult<()> { + let changesets = self.block_meta_manager.delete_rows(row_ids).await?; + for changeset in changesets { + let _ = self.update_block(changeset).await?; + } Ok(()) } @@ -165,6 +207,13 @@ impl ClientGridEditor { .await?; Ok(()) } + + async fn last_block_id(&self) -> FlowyResult { + match self.grid_meta_pad.read().await.get_blocks().last() { + None => Err(FlowyError::internal().context("There is no grid block in this grid")), + Some(grid_block) => Ok(grid_block.id.clone()), + } + } } #[cfg(feature = "flowy_unit_test")] @@ -174,24 +223,6 @@ impl ClientGridEditor { } } -async fn load_all_fields( - grid_pad: &GridMetaPad, - kv_persistence: &Arc, -) -> FlowyResult> { - let field_ids = grid_pad - .fields() - .iter() - .map(|field| field.id.clone()) - .collect::>(); - - let fields = kv_persistence.batch_get::(field_ids)?; - let map = DashMap::new(); - for field in fields { - map.insert(field.id.clone(), field); - } - Ok(map) -} - pub struct GridPadBuilder(); impl RevisionObjectBuilder for GridPadBuilder { type Output = GridMetaPad; diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs index 211af6d340..918d8e7559 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs @@ -1,5 +1,5 @@ use crate::manager::GridUser; -use crate::services::row::{make_row_by_row_id, make_row_ids_per_block, make_rows, RowBuilder}; +use crate::services::row::make_row_ids_per_block; use bytes::Bytes; use dashmap::DashMap; @@ -7,7 +7,9 @@ use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{Field, GridBlock, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset}; +use flowy_grid_data_model::entities::{ + GridBlock, GridBlockChangeset, RepeatedRowOrder, RowMeta, RowMetaChangeset, RowOrder, +}; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_sync::{ RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, @@ -16,19 +18,30 @@ use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; use std::collections::HashMap; + +use dashmap::mapref::one::Ref; use std::sync::Arc; use tokio::sync::RwLock; +type RowId = String; +type BlockId = String; + pub(crate) struct GridBlockMetaEditorManager { user: Arc, editor_map: DashMap>, + block_id_by_row_id: DashMap, } impl GridBlockMetaEditorManager { pub(crate) async fn new(user: &Arc, blocks: Vec) -> FlowyResult { let editor_map = make_block_meta_editor_map(user, blocks).await?; let user = user.clone(); - let manager = Self { user, editor_map }; + let block_id_by_row_id = DashMap::new(); + let manager = Self { + user, + editor_map, + block_id_by_row_id, + }; Ok(manager) } @@ -44,40 +57,98 @@ impl GridBlockMetaEditorManager { } } - pub(crate) async fn create_row(&self, fields: Vec, grid_block: &GridBlock) -> FlowyResult { - let row = RowBuilder::new(&fields, &grid_block.id).build(); - let editor = self.get_editor(&grid_block.id).await?; + pub(crate) async fn create_row(&self, row: RowMeta) -> FlowyResult { + self.block_id_by_row_id.insert(row.id.clone(), row.block_id.clone()); + let editor = self.get_editor(&row.block_id).await?; editor.create_row(row).await } - pub(crate) async fn delete_rows(&self, _row_orders: Option) -> FlowyResult> { - Ok(vec![("".to_owned(), 2)]) - } - - pub(crate) async fn get_all_rows(&self, grid_blocks: Vec, fields: Vec) -> FlowyResult> { - let mut rows = vec![]; - for grid_block in grid_blocks { - let editor = self.get_editor(&grid_block.id).await?; - let row_metas = editor.get_rows(None).await?; - rows.extend(make_rows(&fields, row_metas)); + pub(crate) async fn insert_row( + &self, + rows_by_block_id: HashMap>, + ) -> FlowyResult> { + let mut changesets = vec![]; + for (block_id, rows) in rows_by_block_id { + let editor = self.get_editor(&block_id).await?; + let mut row_count = 0; + for row in rows { + self.block_id_by_row_id.insert(row.id.clone(), row.block_id.clone()); + row_count = editor.create_row(row).await?; + } + changesets.push(GridBlockChangeset::from_row_count(&block_id, row_count)); } - Ok(rows) + + Ok(changesets) } - pub(crate) async fn get_rows(&self, fields: Vec, row_orders: RepeatedRowOrder) -> FlowyResult> { + pub(crate) async fn delete_rows(&self, row_ids: Vec) -> FlowyResult> { + let row_orders = row_ids + .into_iter() + .flat_map(|row_id| match self.block_id_by_row_id.get(&row_id) { + None => None, + Some(block_id) => Some(RowOrder { + row_id, + block_id: block_id.clone(), + }), + }) + .collect::>(); + let mut changesets = vec![]; let row_ids_per_blocks = make_row_ids_per_block(&row_orders); - let mut row_map: HashMap = HashMap::new(); for row_ids_per_block in row_ids_per_blocks { let editor = self.get_editor(&row_ids_per_block.block_id).await?; - let row_metas = editor.get_rows(Some(row_ids_per_block.row_ids)).await?; - row_map.extend(make_row_by_row_id(&fields, row_metas)); + let row_count = editor.delete_rows(row_ids_per_block.row_ids).await?; + + let changeset = GridBlockChangeset::from_row_count(&row_ids_per_block.block_id, row_count); + changesets.push(changeset); } - let rows = row_orders - .iter() - .flat_map(|row_order| row_map.remove(&row_order.row_id)) - .collect::>(); - Ok(rows) + Ok(changesets) + } + + pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { + match self.block_id_by_row_id.get(&changeset.row_id) { + None => { + let msg = format!( + "Update Row failed. Can't find the corresponding block with row_id: {}", + changeset.row_id + ); + Err(FlowyError::internal().context(msg)) + } + Some(block_id) => { + let editor = self.get_editor(&block_id).await?; + editor.update_row(changeset).await + } + } + } + + pub(crate) async fn get_all_rows(&self, grid_blocks: Vec) -> FlowyResult> { + let mut row_metas = vec![]; + for grid_block in grid_blocks { + let editor = self.get_editor(&grid_block.id).await?; + let new_row_metas = editor.get_rows(None).await?; + new_row_metas.iter().for_each(|row_meta| { + self.block_id_by_row_id + .insert(row_meta.id.clone(), row_meta.block_id.clone()); + }); + + row_metas.extend(new_row_metas); + } + Ok(row_metas) + } + + pub(crate) async fn get_rows(&self, row_orders: &RepeatedRowOrder) -> FlowyResult> { + let row_ids_per_blocks = make_row_ids_per_block(row_orders); + let mut row_metas = vec![]; + for row_ids_per_block in row_ids_per_blocks { + let editor = self.get_editor(&row_ids_per_block.block_id).await?; + let new_row_metas = editor.get_rows(Some(row_ids_per_block.row_ids)).await?; + new_row_metas.iter().for_each(|row_meta| { + self.block_id_by_row_id + .insert(row_meta.id.clone(), row_meta.block_id.clone()); + }); + row_metas.extend(new_row_metas); + } + Ok(row_metas) } } @@ -148,9 +219,16 @@ impl ClientGridBlockMetaEditor { Ok(row_count) } - pub async fn delete_rows(&self, ids: Vec) -> FlowyResult<()> { - let _ = self.modify(|pad| Ok(pad.delete_rows(&ids)?)).await?; - Ok(()) + pub async fn delete_rows(&self, ids: Vec) -> FlowyResult { + let mut row_count = 0; + let _ = self + .modify(|pad| { + let changeset = pad.delete_rows(&ids)?; + row_count = pad.number_of_rows(); + Ok(changeset) + }) + .await?; + Ok(row_count) } pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index 0a7918b5d6..03a4f45c69 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -1,5 +1,6 @@ mod util; +pub mod cell; pub mod field; pub mod grid_editor; pub mod grid_meta_editor; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs index cd68038b9c..3a49d5f7e2 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs @@ -1,5 +1,4 @@ -use crate::services::field::*; - +use crate::services::cell::*; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{Field, FieldType}; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index d88b580788..7414c3ba8b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -1,24 +1,60 @@ -use flowy_grid_data_model::entities::{CellMeta, Field, RowMeta}; +use flowy_grid_data_model::entities::{CellMeta, Field, RowMeta, DEFAULT_ROW_HEIGHT}; +use std::collections::HashMap; -pub struct RowBuilder<'a> { - fields: &'a Vec, - row: RowMeta, +pub struct CreateRowContextBuilder<'a> { + #[allow(dead_code)] + fields: &'a [Field], + ctx: CreateRowContext, } -impl<'a> RowBuilder<'a> { - pub fn new(fields: &'a Vec, block_id: &'a String) -> Self { - let row = RowMeta::new(block_id); - Self { fields, row } +impl<'a> CreateRowContextBuilder<'a> { + pub fn new(fields: &'a [Field]) -> Self { + let ctx = CreateRowContext { + row_id: uuid::Uuid::new_v4().to_string(), + cell_by_field_id: Default::default(), + height: DEFAULT_ROW_HEIGHT, + visibility: true, + }; + Self { fields, ctx } } #[allow(dead_code)] pub fn add_cell(mut self, field_id: &str, data: String) -> Self { let cell = CellMeta::new(field_id, data); - self.row.cell_by_field_id.insert(field_id.to_owned(), cell); + self.ctx.cell_by_field_id.insert(field_id.to_owned(), cell); self } - pub fn build(self) -> RowMeta { - self.row + #[allow(dead_code)] + pub fn height(mut self, height: i32) -> Self { + self.ctx.height = height; + self + } + + #[allow(dead_code)] + pub fn visibility(mut self, visibility: bool) -> Self { + self.ctx.visibility = visibility; + self + } + + pub fn build(self) -> CreateRowContext { + self.ctx } } + +pub fn row_meta_from_context(block_id: &str, ctx: CreateRowContext) -> RowMeta { + RowMeta { + id: ctx.row_id, + block_id: block_id.to_owned(), + cell_by_field_id: ctx.cell_by_field_id, + height: ctx.height, + visibility: ctx.visibility, + } +} + +pub struct CreateRowContext { + pub row_id: String, + pub cell_by_field_id: HashMap, + pub height: i32, + pub visibility: bool, +} 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 705871ad93..a1d766b81a 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 @@ -1,5 +1,5 @@ use crate::services::row::stringify_deserialize; -use flowy_grid_data_model::entities::{Cell, CellMeta, Field, RepeatedRowOrder, Row, RowMeta}; +use flowy_grid_data_model::entities::{Cell, CellMeta, Field, RepeatedRowOrder, Row, RowMeta, RowOrder}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; @@ -8,7 +8,7 @@ pub(crate) struct RowIdsPerBlock { pub(crate) row_ids: Vec, } -pub(crate) fn make_row_ids_per_block(row_orders: &RepeatedRowOrder) -> Vec { +pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec { let mut map: HashMap = HashMap::new(); row_orders.iter().for_each(|row_order| { let block_id = row_order.block_id.clone(); @@ -21,7 +21,7 @@ pub(crate) fn make_row_ids_per_block(row_orders: &RepeatedRowOrder) -> Vec>() } -pub(crate) fn make_rows(fields: &Vec, row_metas: Vec) -> Vec { +pub(crate) fn make_rows(fields: &[Field], row_metas: Vec) -> Vec { let field_map = fields .iter() .map(|field| (&field.id, field)) @@ -59,7 +59,7 @@ fn make_cell(field_map: &HashMap<&String, &Field>, field_id: String, raw_cell: C } } -pub(crate) fn make_row_by_row_id(fields: &Vec, row_metas: Vec) -> HashMap { +pub(crate) fn make_row_by_row_id(fields: &[Field], row_metas: Vec) -> HashMap { let field_map = fields .iter() .map(|field| (&field.id, field)) diff --git a/frontend/rust-lib/flowy-grid/src/services/util.rs b/frontend/rust-lib/flowy-grid/src/services/util.rs index a82e748a3e..1639b293a2 100644 --- a/frontend/rust-lib/flowy-grid/src/services/util.rs +++ b/frontend/rust-lib/flowy-grid/src/services/util.rs @@ -1,4 +1,4 @@ -use crate::services::field::MoneySymbol; +use crate::services::cell::MoneySymbol; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; use lazy_static::lazy_static; @@ -99,31 +99,6 @@ fn crop_letters(s: &mut String, pos: usize) { } } -pub fn string_to_bool(bool_str: &str) -> bool { - let lower_case_str: &str = &bool_str.to_lowercase(); - match lower_case_str { - "1" => true, - "true" => true, - "yes" => true, - "0" => false, - "false" => false, - "no" => false, - _ => false, - } -} - pub fn uuid() -> String { uuid::Uuid::new_v4().to_string() } - -pub fn check_type_id(data: &AnyData, field: &Field) -> Result<(), FlowyError> { - let field_type = FieldType::from_type_id(&data.type_id).map_err(|e| FlowyError::internal().context(e))?; - if field_type != field.field_type { - tracing::error!( - "expected field type: {:?} but receive {:?} ", - field_type, - field.field_type - ); - } - Ok(()) -} diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index ef6060837e..80f942751a 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -1,15 +1,16 @@ +use crate::services::cell::*; use crate::services::field::*; use flowy_collaboration::client_grid::{BuildGridInfo, GridBuilder}; use flowy_grid_data_model::entities::FieldType; pub fn make_default_grid(grid_id: &str) -> BuildGridInfo { - let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::new()) + let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::default()) .name("Name") .visibility(true) .field_type(FieldType::RichText) .build(); - let single_select = SingleSelectTypeOptionsBuilder::new() + let single_select = SingleSelectTypeOptionsBuilder::default() .option(SelectOption::new("Done")) .option(SelectOption::new("Progress")); 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 410e7638a5..598bc46eda 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -1,7 +1,10 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; use flowy_grid::services::field::{SelectOption, SingleSelectDescription}; -use flowy_grid_data_model::entities::{FieldChangeset, GridBlock, GridBlockChangeset}; +use flowy_grid::services::row::CreateRowContextBuilder; +use flowy_grid_data_model::entities::{ + FieldChangeset, FieldType, GridBlock, GridBlockChangeset, Row, RowMetaChangeset, +}; #[tokio::test] async fn default_grid_test() { @@ -55,7 +58,7 @@ async fn grid_create_duplicate_field() { #[tokio::test] async fn grid_update_field_with_empty_change() { let single_select_field = create_single_select_field(); - let change = FieldChangeset { + let changeset = FieldChangeset { field_id: single_select_field.id.clone(), name: None, desc: None, @@ -70,7 +73,7 @@ async fn grid_update_field_with_empty_change() { CreateField { field: single_select_field.clone(), }, - UpdateField { change }, + UpdateField { changeset }, AssertFieldEqual { field_index: 2, field: single_select_field, @@ -87,7 +90,7 @@ async fn grid_update_field() { let mut single_select_type_options = SingleSelectDescription::from(&single_select_field); single_select_type_options.options.push(SelectOption::new("Unknown")); - let change = FieldChangeset { + let changeset = FieldChangeset { field_id: single_select_field.id.clone(), name: None, desc: None, @@ -106,7 +109,7 @@ async fn grid_update_field() { CreateField { field: single_select_field.clone(), }, - UpdateField { change }, + UpdateField { changeset }, AssertFieldEqual { field_index: 2, field: cloned_field, @@ -145,7 +148,7 @@ async fn grid_create_block() { async fn grid_update_block() { let grid_block = GridBlock::new(); let mut cloned_grid_block = grid_block.clone(); - let change = GridBlockChangeset { + let changeset = GridBlockChangeset { block_id: grid_block.id.clone(), start_row_index: Some(2), row_count: Some(10), @@ -157,7 +160,7 @@ async fn grid_update_block() { let scripts = vec![ AssertBlockCount(1), CreateBlock { block: grid_block }, - UpdateBlock { change }, + UpdateBlock { changeset }, AssertBlockCount(2), AssertBlockEqual { block_index: 1, @@ -169,6 +172,96 @@ async fn grid_update_block() { #[tokio::test] async fn grid_create_row() { - let scripts = vec![AssertRowCount(3), CreateRow, CreateRow, AssertRowCount(5)]; + let scripts = vec![AssertRowCount(3), CreateEmptyRow, CreateEmptyRow, AssertRowCount(5)]; GridEditorTest::new().await.run_scripts(scripts).await; } + +#[tokio::test] +async fn grid_create_row2() { + let mut test = GridEditorTest::new().await; + let create_row_context = CreateRowContextBuilder::new(&test.fields).build(); + let scripts = vec![ + AssertRowCount(3), + CreateRow { + context: create_row_context, + }, + AssertRowCount(4), + ]; + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_update_row() { + let mut test = GridEditorTest::new().await; + let context = CreateRowContextBuilder::new(&test.fields).build(); + let changeset = RowMetaChangeset { + row_id: context.row_id.clone(), + height: None, + visibility: None, + cell_by_field_id: Default::default(), + }; + + let scripts = vec![ + AssertRowCount(3), + CreateRow { context }, + UpdateRow { + changeset: changeset.clone(), + }, + AssertRow { changeset }, + AssertRowCount(4), + ]; + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_delete_row() { + let mut test = GridEditorTest::new().await; + let context_1 = CreateRowContextBuilder::new(&test.fields).build(); + let context_2 = CreateRowContextBuilder::new(&test.fields).build(); + let row_ids = vec![context_1.row_id.clone(), context_2.row_id.clone()]; + let scripts = vec![ + AssertRowCount(3), + CreateRow { context: context_1 }, + CreateRow { context: context_2 }, + AssertBlockCount(1), + AssertBlock { + block_index: 0, + row_count: 5, + start_row_index: 0, + }, + DeleteRow { row_ids }, + AssertBlock { + block_index: 0, + row_count: 3, + start_row_index: 0, + }, + ]; + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_update_cell() { + let mut test = GridEditorTest::new().await; + let mut builder = CreateRowContextBuilder::new(&test.fields); + for field in &test.fields { + match field.field_type { + FieldType::RichText => { + builder = builder.add_cell(&field.id, "hello world".to_owned()); + } + FieldType::Number => { + builder = builder.add_cell(&field.id, "123".to_owned()); + } + FieldType::DateTime => { + builder = builder.add_cell(&field.id, "March 8, 2022".to_owned()); + } + FieldType::SingleSelect => {} + FieldType::MultiSelect => {} + FieldType::Checkbox => { + builder = builder.add_cell(&field.id, "1".to_owned()); + } + } + } + let context = builder.build(); + let scripts = vec![AssertRowCount(3), CreateRow { context }]; + test.run_scripts(scripts).await; +} diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 278981dab3..e8e6660355 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,8 +1,11 @@ +use flowy_grid::services::cell::*; use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; -use flowy_grid_data_model::entities::{Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset}; +use flowy_grid::services::row::CreateRowContext; +use flowy_grid_data_model::entities::{ + CellMetaChangeset, Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset, Row, RowMeta, RowMetaChangeset, +}; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; - use flowy_test::helper::ViewTest; use flowy_test::FlowySDKTest; use std::sync::Arc; @@ -10,16 +13,52 @@ use std::time::Duration; use tokio::time::sleep; pub enum EditorScript { - CreateField { field: Field }, - UpdateField { change: FieldChangeset }, - DeleteField { field: Field }, + CreateField { + field: Field, + }, + UpdateField { + changeset: FieldChangeset, + }, + DeleteField { + field: Field, + }, AssertFieldCount(usize), - AssertFieldEqual { field_index: usize, field: Field }, - CreateBlock { block: GridBlock }, - UpdateBlock { change: GridBlockChangeset }, + AssertFieldEqual { + field_index: usize, + field: Field, + }, + CreateBlock { + block: GridBlock, + }, + UpdateBlock { + changeset: GridBlockChangeset, + }, AssertBlockCount(usize), - AssertBlockEqual { block_index: usize, block: GridBlock }, - CreateRow, + AssertBlock { + block_index: usize, + row_count: i32, + start_row_index: i32, + }, + AssertBlockEqual { + block_index: usize, + block: GridBlock, + }, + CreateEmptyRow, + CreateRow { + context: CreateRowContext, + }, + UpdateRow { + changeset: RowMetaChangeset, + }, + AssertRow { + changeset: RowMetaChangeset, + }, + DeleteRow { + row_ids: Vec, + }, + UpdateCell { + changeset: CellMetaChangeset, + }, AssertRowCount(usize), // AssertRowEqual{ row_index: usize, row: RowMeta}, AssertGridMetaPad, @@ -29,6 +68,9 @@ pub struct GridEditorTest { pub sdk: FlowySDKTest, pub grid_id: String, pub editor: Arc, + pub fields: Vec, + pub grid_blocks: Vec, + pub row_metas: Vec, } impl GridEditorTest { @@ -37,8 +79,19 @@ impl GridEditorTest { let _ = sdk.init_user().await; let test = ViewTest::new_grid_view(&sdk).await; let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); + let fields = editor.get_fields(None).await.unwrap(); + let grid_blocks = editor.get_blocks().await.unwrap(); + let row_metas = editor.get_row_metas(&None).await.unwrap(); + let grid_id = test.view.id; - Self { sdk, grid_id, editor } + Self { + sdk, + grid_id, + editor, + fields, + grid_blocks, + row_metas, + } } pub async fn run_scripts(&mut self, scripts: Vec) { @@ -56,16 +109,20 @@ impl GridEditorTest { match script { EditorScript::CreateField { field } => { self.editor.create_field(field).await.unwrap(); + self.fields = self.editor.get_fields(None).await.unwrap(); } - EditorScript::UpdateField { change } => { + EditorScript::UpdateField { changeset: change } => { self.editor.update_field(change).await.unwrap(); + self.fields = self.editor.get_fields(None).await.unwrap(); } EditorScript::DeleteField { field } => { self.editor.delete_field(&field.id).await.unwrap(); + self.fields = self.editor.get_fields(None).await.unwrap(); } EditorScript::AssertFieldCount(count) => { assert_eq!(self.editor.get_fields(None).await.unwrap().len(), count); } + EditorScript::AssertFieldEqual { field_index, field } => { let repeated_fields = self.editor.get_fields(None).await.unwrap(); let compared_field = repeated_fields[field_index].clone(); @@ -73,23 +130,60 @@ impl GridEditorTest { } EditorScript::CreateBlock { block } => { self.editor.create_block(block).await.unwrap(); + self.grid_blocks = self.editor.get_blocks().await.unwrap(); } - EditorScript::UpdateBlock { change } => { + EditorScript::UpdateBlock { changeset: change } => { self.editor.update_block(change).await.unwrap(); } EditorScript::AssertBlockCount(count) => { assert_eq!(self.editor.get_blocks().await.unwrap().len(), count); } + EditorScript::AssertBlock { + block_index, + row_count, + start_row_index, + } => { + assert_eq!(self.grid_blocks[block_index].row_count, row_count); + assert_eq!(self.grid_blocks[block_index].start_row_index, start_row_index); + } EditorScript::AssertBlockEqual { block_index, block } => { let blocks = self.editor.get_blocks().await.unwrap(); let compared_block = blocks[block_index].clone(); assert_eq!(compared_block, block); } - EditorScript::CreateRow => { + EditorScript::CreateEmptyRow => { self.editor.create_row().await.unwrap(); + self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); + self.grid_blocks = self.editor.get_blocks().await.unwrap(); + } + EditorScript::CreateRow { context } => { + self.editor.insert_rows(vec![context]).await.unwrap(); + self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); + self.grid_blocks = self.editor.get_blocks().await.unwrap(); + } + EditorScript::UpdateRow { changeset: change } => self.editor.update_row(change).await.unwrap(), + EditorScript::DeleteRow { row_ids } => { + self.editor.delete_rows(row_ids).await.unwrap(); + self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); + self.grid_blocks = self.editor.get_blocks().await.unwrap(); + } + EditorScript::AssertRow { changeset } => { + let row = self.row_metas.iter().find(|row| row.id == changeset.row_id).unwrap(); + + if let Some(visibility) = changeset.visibility { + assert_eq!(row.visibility, visibility); + } + + if let Some(height) = changeset.height { + assert_eq!(row.height, height); + } + } + EditorScript::UpdateCell { changeset } => { + self.editor.update_cell(changeset).await.unwrap(); + self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); } EditorScript::AssertRowCount(count) => { - assert_eq!(self.editor.get_all_rows().await.unwrap().len(), count); + assert_eq!(self.editor.get_rows(None).await.unwrap().len(), count); } EditorScript::AssertGridMetaPad => { sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await; @@ -102,7 +196,7 @@ impl GridEditorTest { } pub fn create_text_field() -> Field { - FieldBuilder::new(RichTextTypeOptionsBuilder::new()) + FieldBuilder::new(RichTextTypeOptionsBuilder::default()) .name("Name") .visibility(true) .field_type(FieldType::RichText) @@ -110,7 +204,7 @@ pub fn create_text_field() -> Field { } pub fn create_single_select_field() -> Field { - let single_select = SingleSelectTypeOptionsBuilder::new() + let single_select = SingleSelectTypeOptionsBuilder::default() .option(SelectOption::new("Done")) .option(SelectOption::new("Progress")); diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index b34f55b39b..5fe63ca7d1 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -33,6 +33,7 @@ impl GridBuilder { pub fn add_empty_row(mut self) -> Self { let row = RowMeta::new(&self.grid_block.id); self.grid_block_meta.rows.push(row); + self.grid_block.row_count += 1; self } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 89d2145e17..d7c9f13928 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -82,41 +82,41 @@ impl GridMetaPad { } } - pub fn update_field(&mut self, change: FieldChangeset) -> CollaborateResult> { - let field_id = change.field_id.clone(); + pub fn update_field(&mut self, changeset: FieldChangeset) -> CollaborateResult> { + let field_id = changeset.field_id.clone(); self.modify_field(&field_id, |field| { let mut is_changed = None; - if let Some(name) = change.name { + if let Some(name) = changeset.name { field.name = name; is_changed = Some(()) } - if let Some(desc) = change.desc { + if let Some(desc) = changeset.desc { field.desc = desc; is_changed = Some(()) } - if let Some(field_type) = change.field_type { + if let Some(field_type) = changeset.field_type { field.field_type = field_type; is_changed = Some(()) } - if let Some(frozen) = change.frozen { + if let Some(frozen) = changeset.frozen { field.frozen = frozen; is_changed = Some(()) } - if let Some(visibility) = change.visibility { + if let Some(visibility) = changeset.visibility { field.visibility = visibility; is_changed = Some(()) } - if let Some(width) = change.width { + if let Some(width) = changeset.width { field.width = width; is_changed = Some(()) } - if let Some(type_options) = change.type_options { + if let Some(type_options) = changeset.type_options { field.type_options = type_options; is_changed = Some(()) } @@ -141,17 +141,17 @@ impl GridMetaPad { self.grid_meta.blocks.clone() } - pub fn update_block(&mut self, change: GridBlockChangeset) -> CollaborateResult> { - let block_id = change.block_id.clone(); + pub fn update_block(&mut self, changeset: GridBlockChangeset) -> CollaborateResult> { + let block_id = changeset.block_id.clone(); self.modify_block(&block_id, |block| { let mut is_changed = None; - if let Some(row_count) = change.row_count { + if let Some(row_count) = changeset.row_count { block.row_count = row_count; is_changed = Some(()); } - if let Some(start_row_index) = change.start_row_index { + if let Some(start_row_index) = changeset.start_row_index { block.start_row_index = start_row_index; is_changed = Some(()); } diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index dee0a2b21b..05de0efa05 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -297,3 +297,36 @@ impl CellMeta { } } } + +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct CellMetaChangeset { + #[pb(index = 1)] + pub row_id: String, + + #[pb(index = 2)] + pub field_id: String, + + #[pb(index = 3, one_of)] + pub data: Option, +} + +impl std::convert::From for RowMetaChangeset { + fn from(changeset: CellMetaChangeset) -> Self { + let mut cell_by_field_id = HashMap::with_capacity(1); + if let Some(data) = changeset.data { + let field_id = changeset.field_id; + let cell_meta = CellMeta { + field_id: field_id.clone(), + data, + }; + cell_by_field_id.insert(field_id, cell_meta); + } + + RowMetaChangeset { + row_id: changeset.row_id, + height: None, + visibility: None, + cell_by_field_id, + } + } +} diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index a9fccf6d54..c8146c452a 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -2956,6 +2956,289 @@ impl ::protobuf::reflect::ProtobufValue for CellMeta { } } +#[derive(PartialEq,Clone,Default)] +pub struct CellMetaChangeset { + // message fields + pub row_id: ::std::string::String, + pub field_id: ::std::string::String, + // message oneof groups + pub one_of_data: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CellMetaChangeset { + fn default() -> &'a CellMetaChangeset { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum CellMetaChangeset_oneof_one_of_data { + data(::std::string::String), +} + +impl CellMetaChangeset { + pub fn new() -> CellMetaChangeset { + ::std::default::Default::default() + } + + // string row_id = 1; + + + pub fn get_row_id(&self) -> &str { + &self.row_id + } + pub fn clear_row_id(&mut self) { + self.row_id.clear(); + } + + // Param is passed by value, moved + pub fn set_row_id(&mut self, v: ::std::string::String) { + self.row_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_id(&mut self) -> &mut ::std::string::String { + &mut self.row_id + } + + // Take field + pub fn take_row_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) + } + + // string field_id = 2; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // string data = 3; + + + pub fn get_data(&self) -> &str { + match self.one_of_data { + ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(ref v)) => v, + _ => "", + } + } + pub fn clear_data(&mut self) { + self.one_of_data = ::std::option::Option::None; + } + + pub fn has_data(&self) -> bool { + match self.one_of_data { + ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_data(&mut self, v: ::std::string::String) { + self.one_of_data = ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(v)) + } + + // Mutable pointer to the field. + pub fn mut_data(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(_)) = self.one_of_data { + } else { + self.one_of_data = ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(::std::string::String::new())); + } + match self.one_of_data { + ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_data(&mut self) -> ::std::string::String { + if self.has_data() { + match self.one_of_data.take() { + ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } +} + +impl ::protobuf::Message for CellMetaChangeset { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_data = ::std::option::Option::Some(CellMetaChangeset_oneof_one_of_data::data(is.read_string()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.row_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.row_id); + } + if !self.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.field_id); + } + if let ::std::option::Option::Some(ref v) = self.one_of_data { + match v { + &CellMetaChangeset_oneof_one_of_data::data(ref v) => { + my_size += ::protobuf::rt::string_size(3, &v); + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.row_id.is_empty() { + os.write_string(1, &self.row_id)?; + } + if !self.field_id.is_empty() { + os.write_string(2, &self.field_id)?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_data { + match v { + &CellMetaChangeset_oneof_one_of_data::data(ref v) => { + os.write_string(3, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> CellMetaChangeset { + CellMetaChangeset::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &CellMetaChangeset| { &m.row_id }, + |m: &mut CellMetaChangeset| { &mut m.row_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &CellMetaChangeset| { &m.field_id }, + |m: &mut CellMetaChangeset| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "data", + CellMetaChangeset::has_data, + CellMetaChangeset::get_data, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CellMetaChangeset", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CellMetaChangeset { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CellMetaChangeset::new) + } +} + +impl ::protobuf::Clear for CellMetaChangeset { + fn clear(&mut self) { + self.row_id.clear(); + self.field_id.clear(); + self.one_of_data = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CellMetaChangeset { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CellMetaChangeset { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum FieldType { RichText = 0, @@ -3059,10 +3342,13 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\ value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"9\n\ \x08CellMeta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\ - \x12\n\x04data\x18\x02\x20\x01(\tR\x04data*d\n\tFieldType\x12\x0c\n\x08R\ - ichText\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\x08Checkbox\x10\x05b\x06proto3\ + \x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"j\n\x11CellMetaChangeset\x12\ + \x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\ + \x02\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x03\x20\x01(\tH\0R\x04\ + dataB\r\n\x0bone_of_data*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\ + \n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingle\ + Select\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\ + \x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 190c400f04..77185fff5d 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -58,6 +58,11 @@ message CellMeta { string field_id = 1; string data = 2; } +message CellMetaChangeset { + string row_id = 1; + string field_id = 2; + oneof one_of_data { string data = 3; }; +} enum FieldType { RichText = 0; Number = 1; From 46be04f94ea8de5a4748e5e13ea178e77b38bfed Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 14 Mar 2022 23:16:25 +0800 Subject: [PATCH 19/28] chore: config update cell --- .../flowy-grid/number_description.pb.dart | 16 +- .../flowy-grid/number_description.pbenum.dart | 20 +- .../flowy-grid/number_description.pbjson.dart | 21 +- .../src/protobuf/model/number_description.rs | 89 ++++--- .../protobuf/proto/number_description.proto | 11 +- ...id_meta_editor.rs => block_meta_editor.rs} | 8 +- .../src/services/cell/builder/mod.rs | 4 +- .../cell/description/checkbox_description.rs | 22 +- .../cell/description/date_description.rs | 119 ++++++++- .../cell/description/number_description.rs | 250 ++++++++++++------ .../cell/description/selection_description.rs | 33 ++- .../cell/description/text_description.rs | 4 +- .../flowy-grid/src/services/grid_editor.rs | 2 +- .../rust-lib/flowy-grid/src/services/mod.rs | 2 +- .../flowy-grid/src/services/row/row_loader.rs | 2 +- .../rust-lib/flowy-grid/src/services/util.rs | 132 +++------ .../flowy-grid/tests/grid/grid_test.rs | 41 ++- .../rust-lib/flowy-grid/tests/grid/script.rs | 4 +- 18 files changed, 486 insertions(+), 294 deletions(-) rename frontend/rust-lib/flowy-grid/src/services/{grid_meta_editor.rs => block_meta_editor.rs} (98%) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart index 395ac5c07f..19064fbfd1 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pb.dart @@ -15,7 +15,7 @@ export 'number_description.pbenum.dart'; class NumberDescription extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'NumberDescription', createEmptyInstance: create) - ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'money', $pb.PbFieldType.OE, defaultOrMaker: MoneySymbol.CNY, valueOf: MoneySymbol.valueOf, enumValues: MoneySymbol.values) + ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'format', $pb.PbFieldType.OE, defaultOrMaker: NumberFormat.Number, valueOf: NumberFormat.valueOf, enumValues: NumberFormat.values) ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scale', $pb.PbFieldType.OU3) ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'symbol') ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signPositive') @@ -25,15 +25,15 @@ class NumberDescription extends $pb.GeneratedMessage { NumberDescription._() : super(); factory NumberDescription({ - MoneySymbol? money, + NumberFormat? format, $core.int? scale, $core.String? symbol, $core.bool? signPositive, $core.String? name, }) { final _result = create(); - if (money != null) { - _result.money = money; + if (format != null) { + _result.format = format; } if (scale != null) { _result.scale = scale; @@ -71,13 +71,13 @@ class NumberDescription extends $pb.GeneratedMessage { static NumberDescription? _defaultInstance; @$pb.TagNumber(1) - MoneySymbol get money => $_getN(0); + NumberFormat get format => $_getN(0); @$pb.TagNumber(1) - set money(MoneySymbol v) { setField(1, v); } + set format(NumberFormat v) { setField(1, v); } @$pb.TagNumber(1) - $core.bool hasMoney() => $_has(0); + $core.bool hasFormat() => $_has(0); @$pb.TagNumber(1) - void clearMoney() => clearField(1); + void clearFormat() => clearField(1); @$pb.TagNumber(2) $core.int get scale => $_getIZ(1); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart index daae771fce..f5c3d38628 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbenum.dart @@ -9,20 +9,22 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; -class MoneySymbol extends $pb.ProtobufEnum { - static const MoneySymbol CNY = MoneySymbol._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CNY'); - static const MoneySymbol EUR = MoneySymbol._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EUR'); - static const MoneySymbol USD = MoneySymbol._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'USD'); +class NumberFormat extends $pb.ProtobufEnum { + static const NumberFormat Number = NumberFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Number'); + static const NumberFormat USD = NumberFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'USD'); + static const NumberFormat CNY = NumberFormat._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CNY'); + static const NumberFormat EUR = NumberFormat._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EUR'); - static const $core.List values = [ + static const $core.List values = [ + Number, + USD, CNY, EUR, - USD, ]; - static final $core.Map<$core.int, MoneySymbol> _byValue = $pb.ProtobufEnum.initByValue(values); - static MoneySymbol? valueOf($core.int value) => _byValue[value]; + static final $core.Map<$core.int, NumberFormat> _byValue = $pb.ProtobufEnum.initByValue(values); + static NumberFormat? valueOf($core.int value) => _byValue[value]; - const MoneySymbol._($core.int v, $core.String n) : super(v, n); + const NumberFormat._($core.int v, $core.String n) : super(v, n); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart index 4a0c8db75a..ff1b3dc40f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_description.pbjson.dart @@ -8,23 +8,24 @@ import 'dart:core' as $core; import 'dart:convert' as $convert; import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use moneySymbolDescriptor instead') -const MoneySymbol$json = const { - '1': 'MoneySymbol', +@$core.Deprecated('Use numberFormatDescriptor instead') +const NumberFormat$json = const { + '1': 'NumberFormat', '2': const [ - const {'1': 'CNY', '2': 0}, - const {'1': 'EUR', '2': 1}, - const {'1': 'USD', '2': 2}, + const {'1': 'Number', '2': 0}, + const {'1': 'USD', '2': 1}, + const {'1': 'CNY', '2': 2}, + const {'1': 'EUR', '2': 3}, ], }; -/// Descriptor for `MoneySymbol`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List moneySymbolDescriptor = $convert.base64Decode('CgtNb25leVN5bWJvbBIHCgNDTlkQABIHCgNFVVIQARIHCgNVU0QQAg=='); +/// Descriptor for `NumberFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List numberFormatDescriptor = $convert.base64Decode('CgxOdW1iZXJGb3JtYXQSCgoGTnVtYmVyEAASBwoDVVNEEAESBwoDQ05ZEAISBwoDRVVSEAM='); @$core.Deprecated('Use numberDescriptionDescriptor instead') const NumberDescription$json = const { '1': 'NumberDescription', '2': const [ - const {'1': 'money', '3': 1, '4': 1, '5': 14, '6': '.MoneySymbol', '10': 'money'}, + const {'1': 'format', '3': 1, '4': 1, '5': 14, '6': '.NumberFormat', '10': 'format'}, const {'1': 'scale', '3': 2, '4': 1, '5': 13, '10': 'scale'}, const {'1': 'symbol', '3': 3, '4': 1, '5': 9, '10': 'symbol'}, const {'1': 'sign_positive', '3': 4, '4': 1, '5': 8, '10': 'signPositive'}, @@ -33,4 +34,4 @@ const NumberDescription$json = const { }; /// Descriptor for `NumberDescription`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List numberDescriptionDescriptor = $convert.base64Decode('ChFOdW1iZXJEZXNjcmlwdGlvbhIiCgVtb25leRgBIAEoDjIMLk1vbmV5U3ltYm9sUgVtb25leRIUCgVzY2FsZRgCIAEoDVIFc2NhbGUSFgoGc3ltYm9sGAMgASgJUgZzeW1ib2wSIwoNc2lnbl9wb3NpdGl2ZRgEIAEoCFIMc2lnblBvc2l0aXZlEhIKBG5hbWUYBSABKAlSBG5hbWU='); +final $typed_data.Uint8List numberDescriptionDescriptor = $convert.base64Decode('ChFOdW1iZXJEZXNjcmlwdGlvbhIlCgZmb3JtYXQYASABKA4yDS5OdW1iZXJGb3JtYXRSBmZvcm1hdBIUCgVzY2FsZRgCIAEoDVIFc2NhbGUSFgoGc3ltYm9sGAMgASgJUgZzeW1ib2wSIwoNc2lnbl9wb3NpdGl2ZRgEIAEoCFIMc2lnblBvc2l0aXZlEhIKBG5hbWUYBSABKAlSBG5hbWU='); diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs index 17bdb557e6..2137ea2be1 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/number_description.rs @@ -26,7 +26,7 @@ #[derive(PartialEq,Clone,Default)] pub struct NumberDescription { // message fields - pub money: MoneySymbol, + pub format: NumberFormat, pub scale: u32, pub symbol: ::std::string::String, pub sign_positive: bool, @@ -47,19 +47,19 @@ impl NumberDescription { ::std::default::Default::default() } - // .MoneySymbol money = 1; + // .NumberFormat format = 1; - pub fn get_money(&self) -> MoneySymbol { - self.money + pub fn get_format(&self) -> NumberFormat { + self.format } - pub fn clear_money(&mut self) { - self.money = MoneySymbol::CNY; + pub fn clear_format(&mut self) { + self.format = NumberFormat::Number; } // Param is passed by value, moved - pub fn set_money(&mut self, v: MoneySymbol) { - self.money = v; + pub fn set_format(&mut self, v: NumberFormat) { + self.format = v; } // uint32 scale = 2; @@ -155,7 +155,7 @@ impl ::protobuf::Message for NumberDescription { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.money, 1, &mut self.unknown_fields)? + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.format, 1, &mut self.unknown_fields)? }, 2 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { @@ -189,8 +189,8 @@ impl ::protobuf::Message for NumberDescription { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if self.money != MoneySymbol::CNY { - my_size += ::protobuf::rt::enum_size(1, self.money); + if self.format != NumberFormat::Number { + my_size += ::protobuf::rt::enum_size(1, self.format); } if self.scale != 0 { my_size += ::protobuf::rt::value_size(2, self.scale, ::protobuf::wire_format::WireTypeVarint); @@ -210,8 +210,8 @@ impl ::protobuf::Message for NumberDescription { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.money != MoneySymbol::CNY { - os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.money))?; + if self.format != NumberFormat::Number { + os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.format))?; } if self.scale != 0 { os.write_uint32(2, self.scale)?; @@ -263,10 +263,10 @@ impl ::protobuf::Message for NumberDescription { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( - "money", - |m: &NumberDescription| { &m.money }, - |m: &mut NumberDescription| { &mut m.money }, + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "format", + |m: &NumberDescription| { &m.format }, + |m: &mut NumberDescription| { &mut m.format }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint32>( "scale", @@ -304,7 +304,7 @@ impl ::protobuf::Message for NumberDescription { impl ::protobuf::Clear for NumberDescription { fn clear(&mut self) { - self.money = MoneySymbol::CNY; + self.format = NumberFormat::Number; self.scale = 0; self.symbol.clear(); self.sign_positive = false; @@ -326,31 +326,34 @@ impl ::protobuf::reflect::ProtobufValue for NumberDescription { } #[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum MoneySymbol { - CNY = 0, - EUR = 1, - USD = 2, +pub enum NumberFormat { + Number = 0, + USD = 1, + CNY = 2, + EUR = 3, } -impl ::protobuf::ProtobufEnum for MoneySymbol { +impl ::protobuf::ProtobufEnum for NumberFormat { fn value(&self) -> i32 { *self as i32 } - fn from_i32(value: i32) -> ::std::option::Option { + fn from_i32(value: i32) -> ::std::option::Option { match value { - 0 => ::std::option::Option::Some(MoneySymbol::CNY), - 1 => ::std::option::Option::Some(MoneySymbol::EUR), - 2 => ::std::option::Option::Some(MoneySymbol::USD), + 0 => ::std::option::Option::Some(NumberFormat::Number), + 1 => ::std::option::Option::Some(NumberFormat::USD), + 2 => ::std::option::Option::Some(NumberFormat::CNY), + 3 => ::std::option::Option::Some(NumberFormat::EUR), _ => ::std::option::Option::None } } fn values() -> &'static [Self] { - static values: &'static [MoneySymbol] = &[ - MoneySymbol::CNY, - MoneySymbol::EUR, - MoneySymbol::USD, + static values: &'static [NumberFormat] = &[ + NumberFormat::Number, + NumberFormat::USD, + NumberFormat::CNY, + NumberFormat::EUR, ]; values } @@ -358,34 +361,34 @@ impl ::protobuf::ProtobufEnum for MoneySymbol { fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("MoneySymbol", file_descriptor_proto()) + ::protobuf::reflect::EnumDescriptor::new_pb_name::("NumberFormat", file_descriptor_proto()) }) } } -impl ::std::marker::Copy for MoneySymbol { +impl ::std::marker::Copy for NumberFormat { } -impl ::std::default::Default for MoneySymbol { +impl ::std::default::Default for NumberFormat { fn default() -> Self { - MoneySymbol::CNY + NumberFormat::Number } } -impl ::protobuf::reflect::ProtobufValue for MoneySymbol { +impl ::protobuf::reflect::ProtobufValue for NumberFormat { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) } } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x18number_description.proto\"\x9e\x01\n\x11NumberDescription\x12\"\n\ - \x05money\x18\x01\x20\x01(\x0e2\x0c.MoneySymbolR\x05money\x12\x14\n\x05s\ - cale\x18\x02\x20\x01(\rR\x05scale\x12\x16\n\x06symbol\x18\x03\x20\x01(\t\ - R\x06symbol\x12#\n\rsign_positive\x18\x04\x20\x01(\x08R\x0csignPositive\ - \x12\x12\n\x04name\x18\x05\x20\x01(\tR\x04name*(\n\x0bMoneySymbol\x12\ - \x07\n\x03CNY\x10\0\x12\x07\n\x03EUR\x10\x01\x12\x07\n\x03USD\x10\x02b\ - \x06proto3\ + \n\x18number_description.proto\"\xa1\x01\n\x11NumberDescription\x12%\n\ + \x06format\x18\x01\x20\x01(\x0e2\r.NumberFormatR\x06format\x12\x14\n\x05\ + scale\x18\x02\x20\x01(\rR\x05scale\x12\x16\n\x06symbol\x18\x03\x20\x01(\ + \tR\x06symbol\x12#\n\rsign_positive\x18\x04\x20\x01(\x08R\x0csignPositiv\ + e\x12\x12\n\x04name\x18\x05\x20\x01(\tR\x04name*5\n\x0cNumberFormat\x12\ + \n\n\x06Number\x10\0\x12\x07\n\x03USD\x10\x01\x12\x07\n\x03CNY\x10\x02\ + \x12\x07\n\x03EUR\x10\x03b\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/number_description.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto index 83ab8b7220..760f6623c4 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_description.proto @@ -1,14 +1,15 @@ syntax = "proto3"; message NumberDescription { - MoneySymbol money = 1; + NumberFormat format = 1; uint32 scale = 2; string symbol = 3; bool sign_positive = 4; string name = 5; } -enum MoneySymbol { - CNY = 0; - EUR = 1; - USD = 2; +enum NumberFormat { + Number = 0; + USD = 1; + CNY = 2; + EUR = 3; } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs similarity index 98% rename from frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs rename to frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index 918d8e7559..3ac75cd70a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -19,7 +19,6 @@ use lib_ot::core::PlainTextAttributes; use std::collections::HashMap; -use dashmap::mapref::one::Ref; use std::sync::Arc; use tokio::sync::RwLock; @@ -84,12 +83,11 @@ impl GridBlockMetaEditorManager { pub(crate) async fn delete_rows(&self, row_ids: Vec) -> FlowyResult> { let row_orders = row_ids .into_iter() - .flat_map(|row_id| match self.block_id_by_row_id.get(&row_id) { - None => None, - Some(block_id) => Some(RowOrder { + .flat_map(|row_id| { + self.block_id_by_row_id.get(&row_id).map(|block_id| RowOrder { row_id, block_id: block_id.clone(), - }), + }) }) .collect::>(); let mut changesets = vec![]; diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs b/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs index a472dec8c5..6812d2c39d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/builder/mod.rs @@ -26,8 +26,8 @@ impl NumberTypeOptionsBuilder { self } - pub fn set_money_symbol(mut self, money_symbol: MoneySymbol) -> Self { - self.0.set_money_symbol(money_symbol); + pub fn set_format(mut self, format: NumberFormat) -> Self { + self.0.set_format(format); self } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs index f6f3603604..97c322bb95 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs @@ -1,6 +1,6 @@ use crate::impl_from_and_to_type_option; use crate::services::row::StringifyCellData; -use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_derive::ProtoBuf; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{Field, FieldType}; use serde::{Deserialize, Serialize}; @@ -38,3 +38,23 @@ fn string_to_bool(bool_str: &str) -> bool { _ => false, } } + +#[cfg(test)] +mod tests { + use crate::services::cell::CheckboxDescription; + use crate::services::row::StringifyCellData; + + #[test] + fn checkout_box_description_test() { + let description = CheckboxDescription::default(); + assert_eq!(description.str_to_cell_data("true").unwrap(), "1".to_owned()); + assert_eq!(description.str_to_cell_data("1").unwrap(), "1".to_owned()); + assert_eq!(description.str_to_cell_data("yes").unwrap(), "1".to_owned()); + + assert_eq!(description.str_to_cell_data("false").unwrap(), "0".to_owned()); + assert_eq!(description.str_to_cell_data("no").unwrap(), "0".to_owned()); + assert_eq!(description.str_to_cell_data("123").unwrap(), "0".to_owned()); + + assert_eq!(description.str_from_cell_data("1".to_owned()), "1".to_owned()); + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs index 09cb04f163..991357f63a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs @@ -1,6 +1,6 @@ use crate::impl_from_and_to_type_option; use crate::services::row::StringifyCellData; -use crate::services::util::*; + use chrono::format::strftime::StrftimeItems; use chrono::NaiveDateTime; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; @@ -8,6 +8,8 @@ use flowy_error::FlowyError; use flowy_grid_data_model::entities::{Field, FieldType}; use serde::{Deserialize, Serialize}; +use strum_macros::EnumIter; + // Date #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] pub struct DateDescription { @@ -20,10 +22,6 @@ pub struct DateDescription { impl_from_and_to_type_option!(DateDescription, FieldType::DateTime); impl DateDescription { - fn date_time_format_str(&self) -> String { - format!("{} {}", self.date_format.format_str(), self.time_format.format_str()) - } - #[allow(dead_code)] fn today_from_timestamp(&self, timestamp: i64) -> String { let native = chrono::NaiveDateTime::from_timestamp(timestamp, 0); @@ -34,7 +32,7 @@ impl DateDescription { let utc: chrono::DateTime = chrono::DateTime::from_utc(naive, chrono::Utc); let local: chrono::DateTime = chrono::DateTime::from(utc); - let fmt_str = self.date_time_format_str(); + let fmt_str = format!("{} {}", self.date_format.format_str(), self.time_format.format_str()); let output = format!("{}", local.format_with_items(StrftimeItems::new(&fmt_str))); output } @@ -55,14 +53,18 @@ impl StringifyCellData for DateDescription { } fn str_to_cell_data(&self, s: &str) -> Result { - let timestamp = s - .parse::() - .map_err(|e| FlowyError::internal().context(format!("Parse {} to i64 failed: {}", s, e)))?; + let timestamp = match s.parse::() { + Ok(timestamp) => timestamp, + Err(e) => { + tracing::error!("Parse {} to i64 failed: {}", s, e); + chrono::Utc::now().timestamp() + } + }; Ok(format!("{}", timestamp)) } } -#[derive(Clone, Debug, Copy, Serialize, Deserialize, ProtoBuf_Enum)] +#[derive(Clone, Debug, Copy, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] pub enum DateFormat { Local = 0, US = 1, @@ -105,7 +107,7 @@ impl DateFormat { } } -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize, ProtoBuf_Enum)] +#[derive(Clone, Copy, PartialEq, Eq, EnumIter, Debug, Hash, Serialize, Deserialize, ProtoBuf_Enum)] pub enum TimeFormat { TwelveHour = 0, TwentyFourHour = 1, @@ -143,3 +145,98 @@ impl std::default::Default for TimeFormat { TimeFormat::TwentyFourHour } } + +#[cfg(test)] +mod tests { + use crate::services::cell::{DateDescription, DateFormat, TimeFormat}; + use crate::services::row::StringifyCellData; + use strum::IntoEnumIterator; + + #[test] + fn date_description_date_format_test() { + let mut description = DateDescription::default(); + let _timestamp = 1647251762; + + for date_format in DateFormat::iter() { + description.date_format = date_format; + match date_format { + DateFormat::Friendly => { + assert_eq!( + "Mar 14,2022 17:56".to_owned(), + description.today_from_timestamp(1647251762) + ); + assert_eq!( + "Mar 14,2022 17:56".to_owned(), + description.str_from_cell_data("1647251762".to_owned()) + ); + } + DateFormat::US => { + assert_eq!( + "2022/03/14 17:56".to_owned(), + description.today_from_timestamp(1647251762) + ); + assert_eq!( + "2022/03/14 17:56".to_owned(), + description.str_from_cell_data("1647251762".to_owned()) + ); + } + DateFormat::ISO => { + assert_eq!( + "2022-03-14 17:56".to_owned(), + description.today_from_timestamp(1647251762) + ); + assert_eq!( + "2022-03-14 17:56".to_owned(), + description.str_from_cell_data("1647251762".to_owned()) + ); + } + DateFormat::Local => { + assert_eq!( + "2022/03/14 17:56".to_owned(), + description.today_from_timestamp(1647251762) + ); + assert_eq!( + "2022/03/14 17:56".to_owned(), + description.str_from_cell_data("1647251762".to_owned()) + ); + } + } + } + } + + #[test] + fn date_description_time_format_test() { + let mut description = DateDescription::default(); + for time_format in TimeFormat::iter() { + description.time_format = time_format; + match time_format { + TimeFormat::TwentyFourHour => { + assert_eq!( + "Mar 14,2022 17:56".to_owned(), + description.today_from_timestamp(1647251762) + ); + assert_eq!( + "Mar 14,2022 17:56".to_owned(), + description.str_from_cell_data("1647251762".to_owned()) + ); + } + TimeFormat::TwelveHour => { + assert_eq!( + "Mar 14,2022 05:56:02 PM".to_owned(), + description.today_from_timestamp(1647251762) + ); + assert_eq!( + "Mar 14,2022 05:56:02 PM".to_owned(), + description.str_from_cell_data("1647251762".to_owned()) + ); + } + } + } + } + + #[test] + fn date_description_invalid_data_test() { + let description = DateDescription::default(); + description.str_to_cell_data("he").unwrap(); + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs index 569d3c8c95..b8470280f0 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs @@ -1,25 +1,62 @@ use crate::impl_from_and_to_type_option; use crate::services::row::StringifyCellData; -use crate::services::util::*; -use chrono::format::strftime::StrftimeItems; -use chrono::NaiveDateTime; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{Field, FieldType}; +use lazy_static::lazy_static; +use rust_decimal::prelude::Zero; use rust_decimal::Decimal; -use rusty_money::{ - iso::{Currency, CNY, EUR, USD}, - Money, -}; +use rusty_money::iso::{Currency, CNY, EUR, USD}; use serde::{Deserialize, Serialize}; + use std::str::FromStr; +use strum::IntoEnumIterator; use strum_macros::EnumIter; +lazy_static! { + static ref STRIP_SYMBOL: Vec = make_strip_symbol(); +} + +#[derive(Clone, Copy, Debug, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] +pub enum NumberFormat { + Number = 0, + USD = 1, + CNY = 2, + EUR = 3, +} + +impl std::default::Default for NumberFormat { + fn default() -> Self { + NumberFormat::Number + } +} + +impl NumberFormat { + pub fn symbol(&self) -> String { + match self { + NumberFormat::Number => "".to_string(), + NumberFormat::USD => USD.symbol.to_string(), + NumberFormat::CNY => CNY.symbol.to_string(), + NumberFormat::EUR => EUR.symbol.to_string(), + } + } + + #[allow(dead_code)] + pub fn code(&self) -> String { + match self { + NumberFormat::Number => "".to_string(), + NumberFormat::USD => USD.iso_alpha_code.to_string(), + NumberFormat::CNY => CNY.iso_alpha_code.to_string(), + NumberFormat::EUR => EUR.iso_alpha_code.to_string(), + } + } +} + // Number #[derive(Clone, Debug, Serialize, Deserialize, ProtoBuf)] pub struct NumberDescription { #[pb(index = 1)] - pub money: MoneySymbol, + pub format: NumberFormat, #[pb(index = 2)] pub scale: u32, @@ -37,10 +74,10 @@ impl_from_and_to_type_option!(NumberDescription, FieldType::Number); impl std::default::Default for NumberDescription { fn default() -> Self { - let money = MoneySymbol::default(); - let symbol = money.symbol_str(); + let format = NumberFormat::default(); + let symbol = format.symbol(); NumberDescription { - money, + format, scale: 0, symbol, sign_positive: true, @@ -50,101 +87,156 @@ impl std::default::Default for NumberDescription { } impl NumberDescription { - pub fn set_money_symbol(&mut self, money_symbol: MoneySymbol) { - self.money = money_symbol; - self.symbol = money_symbol.symbol_str(); + pub fn set_format(&mut self, format: NumberFormat) { + self.format = format; + self.symbol = format.symbol(); } - fn money_from_str(&self, s: &str) -> Option { - match Decimal::from_str(s) { - Ok(mut decimal) => { - match decimal.set_scale(self.scale) { - Ok(_) => {} - Err(e) => { - tracing::error!("Set decimal scale failed: {:?}", e); - } - } - decimal.set_sign_positive(self.sign_positive); - Some(self.money.with_decimal(decimal).to_string()) - } + fn decimal_from_str(&self, s: &str) -> Decimal { + let mut decimal = Decimal::from_str(s).unwrap_or(Decimal::zero()); + match decimal.set_scale(self.scale) { + Ok(_) => {} Err(e) => { - tracing::error!("Parser money from {} failed: {:?}", s, e); - None + tracing::error!("Set decimal scale failed: {:?}", e); } } + decimal.set_sign_positive(self.sign_positive); + decimal + } + + fn money_from_str(&self, s: &str, currency: &'static Currency) -> String { + let decimal = self.decimal_from_str(s); + let money = rusty_money::Money::from_decimal(decimal, currency); + money.to_string() + } + + fn strip_symbol(&self, s: &str) -> String { + let mut s = String::from(s); + if !s.chars().all(char::is_numeric) { + s.retain(|c| !STRIP_SYMBOL.contains(&c.to_string())); + } + s } } impl StringifyCellData for NumberDescription { fn str_from_cell_data(&self, data: String) -> String { - match self.money_from_str(&data) { - Some(money_str) => money_str, - None => String::default(), + match self.format { + NumberFormat::Number => data, + NumberFormat::USD => self.money_from_str(&data, USD), + NumberFormat::CNY => self.money_from_str(&data, CNY), + NumberFormat::EUR => self.money_from_str(&data, EUR), } } fn str_to_cell_data(&self, s: &str) -> Result { - let strip_symbol_money = strip_money_symbol(s); - let decimal = Decimal::from_str(&strip_symbol_money).map_err(|err| FlowyError::internal().context(err))?; - Ok(decimal.to_string()) + Ok(self.strip_symbol(s)) } } -#[derive(Clone, Copy, Debug, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] -pub enum MoneySymbol { - CNY = 0, - EUR = 1, - USD = 2, -} - -impl std::default::Default for MoneySymbol { - fn default() -> Self { - MoneySymbol::USD +fn make_strip_symbol() -> Vec { + let mut symbols = vec![",".to_owned(), ".".to_owned()]; + for format in NumberFormat::iter() { + symbols.push(format.symbol()); } + symbols } -impl MoneySymbol { - // Currency list https://docs.rs/rusty-money/0.4.0/rusty_money/iso/index.html - pub fn from_symbol_str(s: &str) -> MoneySymbol { - match s { - "CNY" => MoneySymbol::CNY, - "EUR" => MoneySymbol::EUR, - "USD" => MoneySymbol::USD, - _ => MoneySymbol::CNY, +#[cfg(test)] +mod tests { + use crate::services::cell::{NumberDescription, NumberFormat}; + use crate::services::row::StringifyCellData; + use strum::IntoEnumIterator; + + #[test] + fn number_description_test() { + let mut description = NumberDescription::default(); + assert_eq!(description.str_to_cell_data("¥18,443").unwrap(), "18443".to_owned()); + assert_eq!(description.str_to_cell_data("$18,443").unwrap(), "18443".to_owned()); + assert_eq!(description.str_to_cell_data("€18.443").unwrap(), "18443".to_owned()); + + for format in NumberFormat::iter() { + description.format = format; + match format { + NumberFormat::Number => { + assert_eq!(description.str_from_cell_data("18443".to_owned()), "18443".to_owned()); + } + NumberFormat::USD => { + assert_eq!(description.str_from_cell_data("18443".to_owned()), "$18,443".to_owned()); + } + NumberFormat::CNY => { + assert_eq!(description.str_from_cell_data("18443".to_owned()), "¥18,443".to_owned()); + } + NumberFormat::EUR => { + assert_eq!(description.str_from_cell_data("18443".to_owned()), "€18.443".to_owned()); + } + } } } - pub fn from_money(money: &rusty_money::Money) -> MoneySymbol { - MoneySymbol::from_symbol_str(&money.currency().symbol.to_string()) - } + #[test] + fn number_description_scale_test() { + let mut description = NumberDescription::default(); + description.scale = 1; - pub fn currency(&self) -> &'static Currency { - match self { - MoneySymbol::CNY => CNY, - MoneySymbol::EUR => EUR, - MoneySymbol::USD => USD, + for format in NumberFormat::iter() { + description.format = format; + match format { + NumberFormat::Number => { + assert_eq!(description.str_from_cell_data("18443".to_owned()), "18443".to_owned()); + } + NumberFormat::USD => { + assert_eq!( + description.str_from_cell_data("18443".to_owned()), + "$1,844.3".to_owned() + ); + } + NumberFormat::CNY => { + assert_eq!( + description.str_from_cell_data("18443".to_owned()), + "¥1,844.3".to_owned() + ); + } + NumberFormat::EUR => { + assert_eq!( + description.str_from_cell_data("18443".to_owned()), + "€1.844,3".to_owned() + ); + } + } } } - // string_to_money("¥18,443").unwrap(); - // string_to_money("$18,443").unwrap(); - // string_to_money("€18,443").unwrap(); - pub fn code(&self) -> String { - self.currency().iso_alpha_code.to_string() - } + #[test] + fn number_description_sign_test() { + let mut description = NumberDescription::default(); + description.sign_positive = false; - pub fn symbol_str(&self) -> String { - self.currency().symbol.to_string() - } - - pub fn zero(&self) -> Money { - let mut decimal = Decimal::new(0, 0); - decimal.set_sign_positive(true); - self.with_decimal(decimal) - } - - pub fn with_decimal(&self, decimal: Decimal) -> Money { - let money = rusty_money::Money::from_decimal(decimal, self.currency()); - money + for format in NumberFormat::iter() { + description.format = format; + match format { + NumberFormat::Number => { + assert_eq!(description.str_from_cell_data("18443".to_owned()), "18443".to_owned()); + } + NumberFormat::USD => { + assert_eq!( + description.str_from_cell_data("18443".to_owned()), + "-$18,443".to_owned() + ); + } + NumberFormat::CNY => { + assert_eq!( + description.str_from_cell_data("18443".to_owned()), + "-¥18,443".to_owned() + ); + } + NumberFormat::EUR => { + assert_eq!( + description.str_from_cell_data("18443".to_owned()), + "-€18.443".to_owned() + ); + } + } + } } } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs index 872210b4b3..3a1485f31e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs @@ -1,7 +1,7 @@ use crate::impl_from_and_to_type_option; use crate::services::row::StringifyCellData; use crate::services::util::*; -use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_derive::ProtoBuf; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{Field, FieldType}; use serde::{Deserialize, Serialize}; @@ -23,7 +23,7 @@ impl StringifyCellData for SingleSelectDescription { } fn str_to_cell_data(&self, s: &str) -> Result { - Ok(s.to_owned()) + Ok(select_option_id_from_data(s.to_owned(), true)) } } @@ -43,10 +43,22 @@ impl StringifyCellData for MultiSelectDescription { } fn str_to_cell_data(&self, s: &str) -> Result { - Ok(s.to_owned()) + Ok(select_option_id_from_data(s.to_owned(), false)) } } +fn select_option_id_from_data(data: String, is_single_select: bool) -> String { + if !is_single_select { + return data; + } + let select_option_ids = data.split(',').collect::>(); + if select_option_ids.is_empty() { + return "".to_owned(); + } + + select_option_ids.split_first().unwrap().0.to_string() +} + #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] pub struct SelectOption { #[pb(index = 1)] @@ -68,3 +80,18 @@ impl SelectOption { } } } + +#[cfg(test)] +mod tests { + use crate::services::cell::{MultiSelectDescription, SingleSelectDescription}; + use crate::services::row::StringifyCellData; + + #[test] + fn selection_description_test() { + let description = SingleSelectDescription::default(); + assert_eq!(description.str_to_cell_data("1,2,3").unwrap(), "1".to_owned()); + + let description = MultiSelectDescription::default(); + assert_eq!(description.str_to_cell_data("1,2,3").unwrap(), "1,2,3".to_owned()); + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs index 228eed240d..4c9786abb7 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs @@ -1,7 +1,7 @@ use crate::impl_from_and_to_type_option; use crate::services::row::StringifyCellData; -use crate::services::util::*; -use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; + +use flowy_derive::ProtoBuf; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{Field, FieldType}; use serde::{Deserialize, Serialize}; 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 c31b1734b3..32bb2d790b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,5 +1,5 @@ use crate::manager::GridUser; -use crate::services::grid_meta_editor::GridBlockMetaEditorManager; +use crate::services::block_meta_editor::GridBlockMetaEditorManager; use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use bytes::Bytes; use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index 03a4f45c69..f8b0422685 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -1,8 +1,8 @@ mod util; +pub mod block_meta_editor; pub mod cell; pub mod field; pub mod grid_editor; -pub mod grid_meta_editor; pub mod kv_persistence; pub mod row; 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 a1d766b81a..6f7640fb1e 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 @@ -1,5 +1,5 @@ use crate::services::row::stringify_deserialize; -use flowy_grid_data_model::entities::{Cell, CellMeta, Field, RepeatedRowOrder, Row, RowMeta, RowOrder}; +use flowy_grid_data_model::entities::{Cell, CellMeta, Field, Row, RowMeta, RowOrder}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; diff --git a/frontend/rust-lib/flowy-grid/src/services/util.rs b/frontend/rust-lib/flowy-grid/src/services/util.rs index 1639b293a2..b5c838fa12 100644 --- a/frontend/rust-lib/flowy-grid/src/services/util.rs +++ b/frontend/rust-lib/flowy-grid/src/services/util.rs @@ -1,103 +1,35 @@ -use crate::services::cell::MoneySymbol; -use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; -use lazy_static::lazy_static; -use rust_decimal::Decimal; -use rusty_money::{iso::Currency, Money}; -use std::collections::HashMap; -use std::str::FromStr; -use strum::IntoEnumIterator; - -lazy_static! { - static ref CURRENCIES_BY_SYMBOL: HashMap = generate_currency_by_symbol(); -} - -#[allow(dead_code)] -fn generate_currency_by_symbol() -> HashMap { - let mut map: HashMap = HashMap::new(); - - for money in MoneySymbol::iter() { - map.insert(money.symbol_str(), money.currency()); - } - map -} - -#[allow(dead_code)] -pub fn string_to_money(money_str: &str) -> Option> { - let mut process_money_str = String::from(money_str); - let default_currency = MoneySymbol::from_symbol_str("CNY").currency(); - - if process_money_str.is_empty() { - return None; - } - - return if process_money_str.chars().all(char::is_numeric) { - match Money::from_str(&process_money_str, default_currency) { - Ok(money) => Some(money), - Err(_) => None, - } - } else { - let symbol = process_money_str.chars().next().unwrap().to_string(); - let mut currency = default_currency; - - for key in CURRENCIES_BY_SYMBOL.keys() { - if symbol.eq(key) { - currency = CURRENCIES_BY_SYMBOL.get(key).unwrap(); - crop_letters(&mut process_money_str, 1); - } - } - - match Money::from_str(&process_money_str, currency) { - Ok(money) => Some(money), - Err(_) => None, - } - }; -} - -#[allow(dead_code)] -pub fn money_from_str(s: &str) -> Option { - match Decimal::from_str(s) { - Ok(mut decimal) => { - match decimal.set_scale(0) { - Ok(_) => {} - Err(e) => { - tracing::error!("Set scale failed. {:?}", e); - } - } - decimal.set_sign_positive(true); - Some(MoneySymbol::USD.with_decimal(decimal).to_string()) - } - Err(e) => { - tracing::debug!("Format {} to money failed, {:?}", s, e); - None - } - } -} - -pub fn strip_money_symbol(money_str: &str) -> String { - let mut process_money_str = String::from(money_str); - - if !process_money_str.chars().all(char::is_numeric) { - let symbol = process_money_str.chars().next().unwrap().to_string(); - for key in CURRENCIES_BY_SYMBOL.keys() { - if symbol.eq(key) { - crop_letters(&mut process_money_str, 1); - } - } - } - process_money_str -} - -fn crop_letters(s: &mut String, pos: usize) { - match s.char_indices().nth(pos) { - Some((pos, _)) => { - s.drain(..pos); - } - None => { - s.clear(); - } - } -} +// +// #[allow(dead_code)] +// pub fn string_to_money(money_str: &str) -> Option> { +// let mut process_money_str = String::from(money_str); +// let default_currency = MoneySymbol::from_symbol_str("CNY").currency(); +// +// if process_money_str.is_empty() { +// return None; +// } +// +// return if process_money_str.chars().all(char::is_numeric) { +// match Money::from_str(&process_money_str, default_currency) { +// Ok(money) => Some(money), +// Err(_) => None, +// } +// } else { +// let symbol = process_money_str.chars().next().unwrap().to_string(); +// let mut currency = default_currency; +// +// for key in CURRENCIES_BY_SYMBOL.keys() { +// if symbol.eq(key) { +// currency = CURRENCIES_BY_SYMBOL.get(key).unwrap(); +// crop_letters(&mut process_money_str, 1); +// } +// } +// +// match Money::from_str(&process_money_str, currency) { +// Ok(money) => Some(money), +// Err(_) => None, +// } +// }; +// } pub fn uuid() -> String { uuid::Uuid::new_v4().to_string() 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 598bc46eda..360407b3b8 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -1,10 +1,8 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; -use flowy_grid::services::field::{SelectOption, SingleSelectDescription}; -use flowy_grid::services::row::CreateRowContextBuilder; -use flowy_grid_data_model::entities::{ - FieldChangeset, FieldType, GridBlock, GridBlockChangeset, Row, RowMetaChangeset, -}; +use flowy_grid::services::cell::*; +use flowy_grid::services::row::{CreateRowContextBuilder, StringifyCellData}; +use flowy_grid_data_model::entities::{FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMetaChangeset}; #[tokio::test] async fn default_grid_test() { @@ -249,19 +247,40 @@ async fn grid_update_cell() { builder = builder.add_cell(&field.id, "hello world".to_owned()); } FieldType::Number => { - builder = builder.add_cell(&field.id, "123".to_owned()); + let description = NumberDescription::from(field); + let data = description.str_to_cell_data("¥18,443").unwrap(); + builder = builder.add_cell(&field.id, data); } FieldType::DateTime => { - builder = builder.add_cell(&field.id, "March 8, 2022".to_owned()); + let description = DateDescription::from(field); + let data = description.str_to_cell_data("1647251762").unwrap(); + builder = builder.add_cell(&field.id, data); + } + FieldType::SingleSelect => { + let description = SingleSelectDescription::from(field); + let options = description.options.first().unwrap(); + let data = description.str_to_cell_data(&options.id).unwrap(); + builder = builder.add_cell(&field.id, data); + } + FieldType::MultiSelect => { + let description = MultiSelectDescription::from(field); + let options = description + .options + .iter() + .map(|option| option.id.clone()) + .collect::>() + .join(","); + let data = description.str_to_cell_data(&options).unwrap(); + builder = builder.add_cell(&field.id, data); } - FieldType::SingleSelect => {} - FieldType::MultiSelect => {} FieldType::Checkbox => { - builder = builder.add_cell(&field.id, "1".to_owned()); + let description = CheckboxDescription::from(field); + let data = description.str_to_cell_data("false").unwrap(); + builder = builder.add_cell(&field.id, data); } } } let context = builder.build(); - let scripts = vec![AssertRowCount(3), CreateRow { context }]; + let scripts = vec![AssertRowCount(3), CreateRow { context }, AssertGridMetaPad]; test.run_scripts(scripts).await; } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index e8e6660355..f123ecc9ed 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -3,7 +3,7 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::row::CreateRowContext; use flowy_grid_data_model::entities::{ - CellMetaChangeset, Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset, Row, RowMeta, RowMetaChangeset, + CellMetaChangeset, Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMeta, RowMetaChangeset, }; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::helper::ViewTest; @@ -104,7 +104,7 @@ impl GridEditorTest { let grid_manager = self.sdk.grid_manager.clone(); let pool = self.sdk.user_session.db_pool().unwrap(); let rev_manager = self.editor.rev_manager(); - let cache = rev_manager.revision_cache().await; + let _cache = rev_manager.revision_cache().await; match script { EditorScript::CreateField { field } => { From 50f32521c50d02b346a62fc8d7adee5d5e62c3d9 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 15 Mar 2022 11:07:18 +0800 Subject: [PATCH 20/28] chore: rename trait --- .../lib/startup/home_deps_resolver.dart | 1 - .../grid/cell_bloc/checkbox_cell_bloc.dart | 1 - .../grid/cell_bloc/date_cell_bloc.dart | 1 - .../grid/cell_bloc/number_cell_bloc.dart | 1 - .../grid/cell_bloc/selection_cell_bloc.dart | 1 - .../grid/cell_bloc/text_cell_bloc.dart | 1 - .../application/grid/column_bloc.dart | 2 +- .../lib/workspace/application/grid/data.dart | 1 - .../application/grid/grid_service.dart | 1 - .../plugins/grid/src/grid_page.dart | 2 +- .../plugins/grid/src/layout/layout.dart | 2 +- .../src/widgets/content/checkbox_cell.dart | 1 - .../grid/src/widgets/content/date_cell.dart | 1 - .../grid/src/widgets/content/number_cell.dart | 1 - .../src/widgets/content/selection_cell.dart | 1 - .../grid/src/widgets/content/text_cell.dart | 1 - .../grid/src/widgets/header/header.dart | 2 +- .../grid/src/widgets/header/header_cell.dart | 2 +- .../flowy-folder-data-model/view.pb.dart | 72 +-- .../flowy-folder-data-model/view.pbjson.dart | 15 +- .../flowy-grid-data-model/grid.pb.dart | 174 +++++ .../flowy-grid-data-model/grid.pbjson.dart | 26 + .../flowy-grid-data-model/meta.pb.dart | 73 +-- .../flowy-grid-data-model/meta.pbjson.dart | 24 +- .../flowy-block/tests/document/script.rs | 2 +- .../src/services/view/controller.rs | 1 - .../flowy-folder/tests/workspace/script.rs | 2 +- .../rust-lib/flowy-grid/src/event_handler.rs | 11 +- frontend/rust-lib/flowy-grid/src/macros.rs | 6 +- .../src/services/block_meta_editor.rs | 42 +- .../cell/description/checkbox_description.rs | 28 +- .../cell/description/date_description.rs | 30 +- .../cell/description/number_description.rs | 62 +- .../cell/description/selection_description.rs | 26 +- .../cell/description/text_description.rs | 12 +- .../src/services/field/field_builder.rs | 28 +- .../flowy-grid/src/services/grid_editor.rs | 37 +- .../src/services/row/cell_data_serde.rs | 32 + .../src/services/row/cell_stringify.rs | 33 - .../flowy-grid/src/services/row/mod.rs | 4 +- .../src/services/row/row_builder.rs | 6 +- .../flowy-grid/src/services/row/row_loader.rs | 25 +- .../flowy-grid/tests/grid/grid_test.rs | 55 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 58 +- .../flowy-net/src/local_server/server.rs | 2 +- frontend/rust-lib/flowy-test/src/helper.rs | 16 +- .../src/client_grid/block_pad.rs | 41 +- .../src/client_grid/grid_builder.rs | 14 +- .../src/client_grid/grid_pad.rs | 39 +- .../src/entities/view.rs | 16 +- .../src/protobuf/model/view.rs | 198 +++--- .../src/protobuf/proto/view.proto | 11 +- .../src/entities/grid.rs | 80 ++- .../src/entities/meta.rs | 40 +- .../src/protobuf/model/grid.rs | 597 +++++++++++++++++- .../src/protobuf/model/meta.rs | 311 +++------ .../src/protobuf/proto/grid.proto | 13 + .../src/protobuf/proto/meta.proto | 7 +- .../flowy-grid-data-model/tests/serde_test.rs | 4 +- 59 files changed, 1444 insertions(+), 852 deletions(-) create mode 100644 frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs delete mode 100644 frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 367390efa0..5b91d8a545 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -13,7 +13,6 @@ import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:get_it/get_it.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index a4ef372a8b..8f0de7fb32 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -1,5 +1,4 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index f24a9ee769..c8b5e97f2d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -1,5 +1,4 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart index 4959b67902..b216550a81 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -1,5 +1,4 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index 615c56f01e..5e7a6e8e22 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -1,5 +1,4 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart index 0aa6c8e1a9..cce4ff9224 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart @@ -1,5 +1,4 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart index 6313920223..39badc922a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/column_bloc.dart @@ -1,4 +1,4 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +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'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart index 96f89c9eb0..c32f87f1a2 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -1,6 +1,5 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:equatable/equatable.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; class GridInfo { List rows; diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index a3f7f68760..e519b0a90d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -3,7 +3,6 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:dartz/dartz.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; class GridService { Future> openGrid({required String gridId}) async { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index 46c14d9b8d..7435ea0e5f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -6,7 +6,7 @@ import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_scrollview.dart'; import 'package:flowy_infra_ui/widget/error_page.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter/material.dart'; import 'package:styled_widget/styled_widget.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart index 14f4a672cf..3f076fc89f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart @@ -1,4 +1,4 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'sizes.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart index ffa94d428e..d3d2b57735 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart @@ -1,7 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart index f36bdb386c..e1661fdffa 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart @@ -1,7 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/date_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart index 143f741b15..86b9863019 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart @@ -1,7 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/number_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart index 6dc2a1922a..047cff7475 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart @@ -1,7 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; class SingleSelectCell extends StatefulWidget { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart index eef2f79195..7661ddc22f 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -1,7 +1,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index 6a2adc619e..83d24535f4 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -5,7 +5,7 @@ import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index 6217c9c344..aacdcd251e 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -2,7 +2,7 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.d import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart index b79716fd25..350b5eac85 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart @@ -275,8 +275,8 @@ class CreateViewPayload extends $pb.GeneratedMessage { ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) - ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData') - ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) + ..a<$core.int>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) + ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') ..hasRequiredFields = false ; @@ -287,8 +287,8 @@ class CreateViewPayload extends $pb.GeneratedMessage { $core.String? desc, $core.String? thumbnail, ViewDataType? dataType, - $core.String? extData, $core.int? pluginType, + $core.String? data, }) { final _result = create(); if (belongToId != null) { @@ -306,12 +306,12 @@ class CreateViewPayload extends $pb.GeneratedMessage { if (dataType != null) { _result.dataType = dataType; } - if (extData != null) { - _result.extData = extData; - } if (pluginType != null) { _result.pluginType = pluginType; } + if (data != null) { + _result.data = data; + } return _result; } factory CreateViewPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -384,22 +384,22 @@ class CreateViewPayload extends $pb.GeneratedMessage { void clearDataType() => clearField(5); @$pb.TagNumber(6) - $core.String get extData => $_getSZ(5); + $core.int get pluginType => $_getIZ(5); @$pb.TagNumber(6) - set extData($core.String v) { $_setString(5, v); } + set pluginType($core.int v) { $_setSignedInt32(5, v); } @$pb.TagNumber(6) - $core.bool hasExtData() => $_has(5); + $core.bool hasPluginType() => $_has(5); @$pb.TagNumber(6) - void clearExtData() => clearField(6); + void clearPluginType() => clearField(6); @$pb.TagNumber(7) - $core.int get pluginType => $_getIZ(6); + $core.String get data => $_getSZ(6); @$pb.TagNumber(7) - set pluginType($core.int v) { $_setSignedInt32(6, v); } + set data($core.String v) { $_setString(6, v); } @$pb.TagNumber(7) - $core.bool hasPluginType() => $_has(6); + $core.bool hasData() => $_has(6); @$pb.TagNumber(7) - void clearPluginType() => clearField(7); + void clearData() => clearField(7); } class CreateViewParams extends $pb.GeneratedMessage { @@ -409,10 +409,9 @@ class CreateViewParams extends $pb.GeneratedMessage { ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) - ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData') - ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewId') - ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') - ..a<$core.int>(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) + ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewId') + ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') + ..a<$core.int>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) ..hasRequiredFields = false ; @@ -423,7 +422,6 @@ class CreateViewParams extends $pb.GeneratedMessage { $core.String? desc, $core.String? thumbnail, ViewDataType? dataType, - $core.String? extData, $core.String? viewId, $core.String? data, $core.int? pluginType, @@ -444,9 +442,6 @@ class CreateViewParams extends $pb.GeneratedMessage { if (dataType != null) { _result.dataType = dataType; } - if (extData != null) { - _result.extData = extData; - } if (viewId != null) { _result.viewId = viewId; } @@ -525,40 +520,31 @@ class CreateViewParams extends $pb.GeneratedMessage { void clearDataType() => clearField(5); @$pb.TagNumber(6) - $core.String get extData => $_getSZ(5); + $core.String get viewId => $_getSZ(5); @$pb.TagNumber(6) - set extData($core.String v) { $_setString(5, v); } + set viewId($core.String v) { $_setString(5, v); } @$pb.TagNumber(6) - $core.bool hasExtData() => $_has(5); + $core.bool hasViewId() => $_has(5); @$pb.TagNumber(6) - void clearExtData() => clearField(6); + void clearViewId() => clearField(6); @$pb.TagNumber(7) - $core.String get viewId => $_getSZ(6); + $core.String get data => $_getSZ(6); @$pb.TagNumber(7) - set viewId($core.String v) { $_setString(6, v); } + set data($core.String v) { $_setString(6, v); } @$pb.TagNumber(7) - $core.bool hasViewId() => $_has(6); + $core.bool hasData() => $_has(6); @$pb.TagNumber(7) - void clearViewId() => clearField(7); + void clearData() => clearField(7); @$pb.TagNumber(8) - $core.String get data => $_getSZ(7); + $core.int get pluginType => $_getIZ(7); @$pb.TagNumber(8) - set data($core.String v) { $_setString(7, v); } + set pluginType($core.int v) { $_setSignedInt32(7, v); } @$pb.TagNumber(8) - $core.bool hasData() => $_has(7); + $core.bool hasPluginType() => $_has(7); @$pb.TagNumber(8) - void clearData() => clearField(8); - - @$pb.TagNumber(9) - $core.int get pluginType => $_getIZ(8); - @$pb.TagNumber(9) - set pluginType($core.int v) { $_setSignedInt32(8, v); } - @$pb.TagNumber(9) - $core.bool hasPluginType() => $_has(8); - @$pb.TagNumber(9) - void clearPluginType() => clearField(9); + void clearPluginType() => clearField(8); } class ViewId extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart index adb1721475..358cb41100 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart @@ -59,8 +59,8 @@ const CreateViewPayload$json = const { const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'}, const {'1': 'thumbnail', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'thumbnail'}, const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'}, - const {'1': 'ext_data', '3': 6, '4': 1, '5': 9, '10': 'extData'}, - const {'1': 'plugin_type', '3': 7, '4': 1, '5': 5, '10': 'pluginType'}, + const {'1': 'plugin_type', '3': 6, '4': 1, '5': 5, '10': 'pluginType'}, + const {'1': 'data', '3': 7, '4': 1, '5': 9, '10': 'data'}, ], '8': const [ const {'1': 'one_of_thumbnail'}, @@ -68,7 +68,7 @@ const CreateViewPayload$json = const { }; /// Descriptor for `CreateViewPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createViewPayloadDescriptor = $convert.base64Decode('ChFDcmVhdGVWaWV3UGF5bG9hZBIgCgxiZWxvbmdfdG9faWQYASABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEh4KCXRodW1ibmFpbBgEIAEoCUgAUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIZCghleHRfZGF0YRgGIAEoCVIHZXh0RGF0YRIfCgtwbHVnaW5fdHlwZRgHIAEoBVIKcGx1Z2luVHlwZUISChBvbmVfb2ZfdGh1bWJuYWls'); +final $typed_data.Uint8List createViewPayloadDescriptor = $convert.base64Decode('ChFDcmVhdGVWaWV3UGF5bG9hZBIgCgxiZWxvbmdfdG9faWQYASABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEh4KCXRodW1ibmFpbBgEIAEoCUgAUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIfCgtwbHVnaW5fdHlwZRgGIAEoBVIKcGx1Z2luVHlwZRISCgRkYXRhGAcgASgJUgRkYXRhQhIKEG9uZV9vZl90aHVtYm5haWw='); @$core.Deprecated('Use createViewParamsDescriptor instead') const CreateViewParams$json = const { '1': 'CreateViewParams', @@ -78,15 +78,14 @@ const CreateViewParams$json = const { const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'}, const {'1': 'thumbnail', '3': 4, '4': 1, '5': 9, '10': 'thumbnail'}, const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'}, - const {'1': 'ext_data', '3': 6, '4': 1, '5': 9, '10': 'extData'}, - const {'1': 'view_id', '3': 7, '4': 1, '5': 9, '10': 'viewId'}, - const {'1': 'data', '3': 8, '4': 1, '5': 9, '10': 'data'}, - const {'1': 'plugin_type', '3': 9, '4': 1, '5': 5, '10': 'pluginType'}, + const {'1': 'view_id', '3': 6, '4': 1, '5': 9, '10': 'viewId'}, + const {'1': 'data', '3': 7, '4': 1, '5': 9, '10': 'data'}, + const {'1': 'plugin_type', '3': 8, '4': 1, '5': 5, '10': 'pluginType'}, ], }; /// Descriptor for `CreateViewParams`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createViewParamsDescriptor = $convert.base64Decode('ChBDcmVhdGVWaWV3UGFyYW1zEiAKDGJlbG9uZ190b19pZBgBIAEoCVIKYmVsb25nVG9JZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSHAoJdGh1bWJuYWlsGAQgASgJUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIZCghleHRfZGF0YRgGIAEoCVIHZXh0RGF0YRIXCgd2aWV3X2lkGAcgASgJUgZ2aWV3SWQSEgoEZGF0YRgIIAEoCVIEZGF0YRIfCgtwbHVnaW5fdHlwZRgJIAEoBVIKcGx1Z2luVHlwZQ=='); +final $typed_data.Uint8List createViewParamsDescriptor = $convert.base64Decode('ChBDcmVhdGVWaWV3UGFyYW1zEiAKDGJlbG9uZ190b19pZBgBIAEoCVIKYmVsb25nVG9JZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSHAoJdGh1bWJuYWlsGAQgASgJUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIXCgd2aWV3X2lkGAYgASgJUgZ2aWV3SWQSEgoEZGF0YRgHIAEoCVIEZGF0YRIfCgtwbHVnaW5fdHlwZRgIIAEoBVIKcGx1Z2luVHlwZQ=='); @$core.Deprecated('Use viewIdDescriptor instead') const ViewId$json = const { '1': 'ViewId', 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 4122de9503..60a0502420 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 @@ -9,6 +9,8 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; +import 'meta.pbenum.dart' as $0; + class Grid extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Grid', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') @@ -72,6 +74,137 @@ class Grid extends $pb.GeneratedMessage { $core.List get rowOrders => $_getList(2); } +class Field extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Field', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') + ..e<$0.FieldType>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: $0.FieldType.RichText, valueOf: $0.FieldType.valueOf, enumValues: $0.FieldType.values) + ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') + ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') + ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) + ..hasRequiredFields = false + ; + + Field._() : super(); + factory Field({ + $core.String? id, + $core.String? name, + $core.String? desc, + $0.FieldType? fieldType, + $core.bool? frozen, + $core.bool? visibility, + $core.int? width, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (name != null) { + _result.name = name; + } + if (desc != null) { + _result.desc = desc; + } + if (fieldType != null) { + _result.fieldType = fieldType; + } + if (frozen != null) { + _result.frozen = frozen; + } + if (visibility != null) { + _result.visibility = visibility; + } + if (width != null) { + _result.width = width; + } + return _result; + } + factory Field.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Field.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Field clone() => Field()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Field copyWith(void Function(Field) updates) => super.copyWith((message) => updates(message as Field)) as Field; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Field create() => Field._(); + Field createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Field getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Field? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get id => $_getSZ(0); + @$pb.TagNumber(1) + set id($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get name => $_getSZ(1); + @$pb.TagNumber(2) + set name($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasName() => $_has(1); + @$pb.TagNumber(2) + void clearName() => clearField(2); + + @$pb.TagNumber(3) + $core.String get desc => $_getSZ(2); + @$pb.TagNumber(3) + set desc($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasDesc() => $_has(2); + @$pb.TagNumber(3) + void clearDesc() => clearField(3); + + @$pb.TagNumber(4) + $0.FieldType get fieldType => $_getN(3); + @$pb.TagNumber(4) + set fieldType($0.FieldType v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasFieldType() => $_has(3); + @$pb.TagNumber(4) + void clearFieldType() => clearField(4); + + @$pb.TagNumber(5) + $core.bool get frozen => $_getBF(4); + @$pb.TagNumber(5) + set frozen($core.bool v) { $_setBool(4, v); } + @$pb.TagNumber(5) + $core.bool hasFrozen() => $_has(4); + @$pb.TagNumber(5) + void clearFrozen() => clearField(5); + + @$pb.TagNumber(6) + $core.bool get visibility => $_getBF(5); + @$pb.TagNumber(6) + set visibility($core.bool v) { $_setBool(5, v); } + @$pb.TagNumber(6) + $core.bool hasVisibility() => $_has(5); + @$pb.TagNumber(6) + void clearVisibility() => clearField(6); + + @$pb.TagNumber(7) + $core.int get width => $_getIZ(6); + @$pb.TagNumber(7) + set width($core.int v) { $_setSignedInt32(6, v); } + @$pb.TagNumber(7) + $core.bool hasWidth() => $_has(6); + @$pb.TagNumber(7) + void clearWidth() => clearField(7); +} + class FieldOrder extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldOrder', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') @@ -119,6 +252,47 @@ class FieldOrder extends $pb.GeneratedMessage { void clearFieldId() => clearField(1); } +class RepeatedField extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedField', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Field.create) + ..hasRequiredFields = false + ; + + RepeatedField._() : super(); + factory RepeatedField({ + $core.Iterable? items, + }) { + final _result = create(); + if (items != null) { + _result.items.addAll(items); + } + return _result; + } + factory RepeatedField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedField.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RepeatedField clone() => RepeatedField()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RepeatedField copyWith(void Function(RepeatedField) updates) => super.copyWith((message) => updates(message as RepeatedField)) as RepeatedField; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RepeatedField create() => RepeatedField._(); + RepeatedField createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RepeatedField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedField? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get items => $_getList(0); +} + class RepeatedFieldOrder extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedFieldOrder', createEmptyInstance: create) ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: FieldOrder.create) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index 2c1a16296d..0dc1fd25f6 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 @@ -20,6 +20,22 @@ const Grid$json = const { /// Descriptor for `Grid`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxIoCgpyb3dfb3JkZXJzGAMgAygLMgkuUm93T3JkZXJSCXJvd09yZGVycw=='); +@$core.Deprecated('Use fieldDescriptor instead') +const Field$json = const { + '1': 'Field', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, + const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'}, + const {'1': 'field_type', '3': 4, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'}, + const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'}, + const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'}, + const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'}, + ], +}; + +/// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aA=='); @$core.Deprecated('Use fieldOrderDescriptor instead') const FieldOrder$json = const { '1': 'FieldOrder', @@ -30,6 +46,16 @@ const FieldOrder$json = const { /// Descriptor for `FieldOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElk'); +@$core.Deprecated('Use repeatedFieldDescriptor instead') +const RepeatedField$json = const { + '1': 'RepeatedField', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Field', '10': 'items'}, + ], +}; + +/// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z'); @$core.Deprecated('Use repeatedFieldOrderDescriptor instead') const RepeatedFieldOrder$json = const { '1': 'RepeatedFieldOrder', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 12dbec7975..49168b0274 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -16,7 +16,7 @@ export 'meta.pbenum.dart'; class GridMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: Field.create) + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: GridBlock.create) ..hasRequiredFields = false ; @@ -24,7 +24,7 @@ class GridMeta extends $pb.GeneratedMessage { GridMeta._() : super(); factory GridMeta({ $core.String? gridId, - $core.Iterable? fields, + $core.Iterable? fields, $core.Iterable? blocks, }) { final _result = create(); @@ -70,7 +70,7 @@ class GridMeta extends $pb.GeneratedMessage { void clearGridId() => clearField(1); @$pb.TagNumber(2) - $core.List get fields => $_getList(1); + $core.List get fields => $_getList(1); @$pb.TagNumber(3) $core.List get blocks => $_getList(2); @@ -206,8 +206,8 @@ class GridBlockMeta extends $pb.GeneratedMessage { $core.List get rows => $_getList(1); } -class Field extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Field', createEmptyInstance: create) +class FieldMeta extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc') @@ -219,8 +219,8 @@ class Field extends $pb.GeneratedMessage { ..hasRequiredFields = false ; - Field._() : super(); - factory Field({ + FieldMeta._() : super(); + factory FieldMeta({ $core.String? id, $core.String? name, $core.String? desc, @@ -257,26 +257,26 @@ class Field extends $pb.GeneratedMessage { } return _result; } - factory Field.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Field.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory FieldMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory FieldMeta.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - Field clone() => Field()..mergeFromMessage(this); + FieldMeta clone() => FieldMeta()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - Field copyWith(void Function(Field) updates) => super.copyWith((message) => updates(message as Field)) as Field; // ignore: deprecated_member_use + FieldMeta copyWith(void Function(FieldMeta) updates) => super.copyWith((message) => updates(message as FieldMeta)) as FieldMeta; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static Field create() => Field._(); - Field createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static FieldMeta create() => FieldMeta._(); + FieldMeta createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static Field getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static Field? _defaultInstance; + static FieldMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static FieldMeta? _defaultInstance; @$pb.TagNumber(1) $core.String get id => $_getSZ(0); @@ -587,47 +587,6 @@ class FieldChangeset extends $pb.GeneratedMessage { void clearTypeOptions() => clearField(8); } -class RepeatedField extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedField', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Field.create) - ..hasRequiredFields = false - ; - - RepeatedField._() : super(); - factory RepeatedField({ - $core.Iterable? items, - }) { - final _result = create(); - if (items != null) { - _result.items.addAll(items); - } - return _result; - } - factory RepeatedField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RepeatedField.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RepeatedField clone() => RepeatedField()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RepeatedField copyWith(void Function(RepeatedField) updates) => super.copyWith((message) => updates(message as RepeatedField)) as RepeatedField; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RepeatedField create() => RepeatedField._(); - RepeatedField createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RepeatedField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RepeatedField? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get items => $_getList(0); -} - class AnyData extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AnyData', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeId') diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 728367ea13..3921f443c4 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -28,13 +28,13 @@ const GridMeta$json = const { '1': 'GridMeta', '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.Field', '10': 'fields'}, + const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fields'}, const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlock', '10': 'blocks'}, ], }; /// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIiCgZibG9ja3MYAyADKAsyCi5HcmlkQmxvY2tSBmJsb2Nrcw=='); +final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSIgoGYmxvY2tzGAMgAygLMgouR3JpZEJsb2NrUgZibG9ja3M='); @$core.Deprecated('Use gridBlockDescriptor instead') const GridBlock$json = const { '1': 'GridBlock', @@ -58,9 +58,9 @@ const GridBlockMeta$json = const { /// Descriptor for `GridBlockMeta`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridBlockMetaDescriptor = $convert.base64Decode('Cg1HcmlkQmxvY2tNZXRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEhwKBHJvd3MYAiADKAsyCC5Sb3dNZXRhUgRyb3dz'); -@$core.Deprecated('Use fieldDescriptor instead') -const Field$json = const { - '1': 'Field', +@$core.Deprecated('Use fieldMetaDescriptor instead') +const FieldMeta$json = const { + '1': 'FieldMeta', '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, @@ -73,8 +73,8 @@ const Field$json = const { ], }; -/// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIhCgx0eXBlX29wdGlvbnMYCCABKAlSC3R5cGVPcHRpb25z'); +/// Descriptor for `FieldMeta`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldMetaDescriptor = $convert.base64Decode('CglGaWVsZE1ldGESDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIpCgpmaWVsZF90eXBlGAQgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSFgoGZnJvemVuGAUgASgIUgZmcm96ZW4SHgoKdmlzaWJpbGl0eRgGIAEoCFIKdmlzaWJpbGl0eRIUCgV3aWR0aBgHIAEoBVIFd2lkdGgSIQoMdHlwZV9vcHRpb25zGAggASgJUgt0eXBlT3B0aW9ucw=='); @$core.Deprecated('Use fieldChangesetDescriptor instead') const FieldChangeset$json = const { '1': 'FieldChangeset', @@ -101,16 +101,6 @@ const FieldChangeset$json = const { /// Descriptor for `FieldChangeset`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldChangesetDescriptor = $convert.base64Decode('Cg5GaWVsZENoYW5nZXNldBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBIUCgRuYW1lGAIgASgJSABSBG5hbWUSFAoEZGVzYxgDIAEoCUgBUgRkZXNjEisKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVIAlIJZmllbGRUeXBlEhgKBmZyb3plbhgFIAEoCEgDUgZmcm96ZW4SIAoKdmlzaWJpbGl0eRgGIAEoCEgEUgp2aXNpYmlsaXR5EhYKBXdpZHRoGAcgASgFSAVSBXdpZHRoEiMKDHR5cGVfb3B0aW9ucxgIIAEoCUgGUgt0eXBlT3B0aW9uc0INCgtvbmVfb2ZfbmFtZUINCgtvbmVfb2ZfZGVzY0ITChFvbmVfb2ZfZmllbGRfdHlwZUIPCg1vbmVfb2ZfZnJvemVuQhMKEW9uZV9vZl92aXNpYmlsaXR5Qg4KDG9uZV9vZl93aWR0aEIVChNvbmVfb2ZfdHlwZV9vcHRpb25z'); -@$core.Deprecated('Use repeatedFieldDescriptor instead') -const RepeatedField$json = const { - '1': 'RepeatedField', - '2': const [ - const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Field', '10': 'items'}, - ], -}; - -/// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z'); @$core.Deprecated('Use anyDataDescriptor instead') const AnyData$json = const { '1': 'AnyData', diff --git a/frontend/rust-lib/flowy-block/tests/document/script.rs b/frontend/rust-lib/flowy-block/tests/document/script.rs index af237de010..2ae6e14fc9 100644 --- a/frontend/rust-lib/flowy-block/tests/document/script.rs +++ b/frontend/rust-lib/flowy-block/tests/document/script.rs @@ -26,7 +26,7 @@ impl TextBlockEditorTest { pub async fn new() -> Self { let sdk = FlowySDKTest::default(); let _ = sdk.init_user().await; - let test = ViewTest::new_grid_view(&sdk).await; + let test = ViewTest::new_text_block_view(&sdk).await; let editor = sdk.text_block_manager.open_block(&test.view.id).await.unwrap(); Self { sdk, editor } } 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 79ce91e3bb..2d943df032 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -171,7 +171,6 @@ impl ViewController { data_type: view.data_type, data: delta_str, view_id: uuid(), - ext_data: view.ext_data, plugin_type: view.plugin_type, }; diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index 9c2c8ecbed..3cb65a414c 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs @@ -350,8 +350,8 @@ pub async fn create_view(sdk: &FlowySDKTest, app_id: &str, name: &str, desc: &st desc: desc.to_string(), thumbnail: None, data_type, - ext_data: "".to_string(), plugin_type: 0, + data: "".to_string(), }; let view = FolderEventBuilder::new(sdk.clone()) .event(CreateView) diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 5aa786431b..5028a40407 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,7 +1,7 @@ use crate::manager::GridManager; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ - Cell, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedRow, + Cell, Field, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedRow, }; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -13,7 +13,7 @@ pub(crate) async fn get_grid_data_handler( ) -> DataResult { let grid_id: GridId = data.into_inner(); let editor = manager.open_grid(grid_id).await?; - let grid = editor.grid_data().await; + let grid = editor.grid_data().await?; data_result(grid) } @@ -35,7 +35,12 @@ pub(crate) async fn get_fields_handler( ) -> DataResult { let payload: QueryFieldPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_field: RepeatedField = editor.get_fields(Some(payload.field_orders)).await?.into(); + let field_metas = editor.get_field_metas(Some(payload.field_orders)).await?; + let repeated_field: RepeatedField = field_metas + .into_iter() + .map(|field_meta| Field::from(field_meta)) + .collect::>() + .into(); data_result(repeated_field) } diff --git a/frontend/rust-lib/flowy-grid/src/macros.rs b/frontend/rust-lib/flowy-grid/src/macros.rs index ce638f96b8..d7a5fc8bf8 100644 --- a/frontend/rust-lib/flowy-grid/src/macros.rs +++ b/frontend/rust-lib/flowy-grid/src/macros.rs @@ -9,9 +9,9 @@ macro_rules! impl_from_and_to_type_option { #[macro_export] macro_rules! impl_from_field_type_option { ($target: ident) => { - impl std::convert::From<&Field> for $target { - fn from(field: &Field) -> $target { - match serde_json::from_str(&field.type_options) { + impl std::convert::From<&FieldMeta> for $target { + fn from(field_meta: &FieldMeta) -> $target { + match serde_json::from_str(&field_meta.type_options) { Ok(obj) => obj, Err(err) => { tracing::error!("{} convert from any data failed, {:?}", stringify!($target), err); 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 3ac75cd70a..c691e0b12c 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 @@ -119,11 +119,11 @@ impl GridBlockMetaEditorManager { } } - pub(crate) async fn get_all_rows(&self, grid_blocks: Vec) -> FlowyResult> { + pub(crate) async fn get_all_rows(&self, grid_blocks: Vec) -> FlowyResult>> { let mut row_metas = vec![]; for grid_block in grid_blocks { let editor = self.get_editor(&grid_block.id).await?; - let new_row_metas = editor.get_rows(None).await?; + let new_row_metas = editor.get_row_metas(None).await?; new_row_metas.iter().for_each(|row_meta| { self.block_id_by_row_id .insert(row_meta.id.clone(), row_meta.block_id.clone()); @@ -134,12 +134,23 @@ impl GridBlockMetaEditorManager { Ok(row_metas) } - pub(crate) async fn get_rows(&self, row_orders: &RepeatedRowOrder) -> FlowyResult> { + pub(crate) async fn get_row_orders(&self, grid_blocks: Vec) -> FlowyResult> { + let mut row_orders = vec![]; + for grid_block in grid_blocks { + let editor = self.get_editor(&grid_block.id).await?; + let row_metas = editor.get_row_metas(None).await?; + let block_row_orders = row_metas.iter().map(|row_meta| RowOrder::from(row_meta)); + row_orders.extend(block_row_orders); + } + Ok(row_orders) + } + + pub(crate) async fn get_rows(&self, row_orders: &RepeatedRowOrder) -> FlowyResult>> { let row_ids_per_blocks = make_row_ids_per_block(row_orders); let mut row_metas = vec![]; for row_ids_per_block in row_ids_per_blocks { let editor = self.get_editor(&row_ids_per_block.block_id).await?; - let new_row_metas = editor.get_rows(Some(row_ids_per_block.row_ids)).await?; + let new_row_metas = editor.get_row_metas(Some(row_ids_per_block.row_ids)).await?; new_row_metas.iter().for_each(|row_meta| { self.block_id_by_row_id .insert(row_meta.id.clone(), row_meta.block_id.clone()); @@ -234,14 +245,21 @@ impl ClientGridBlockMetaEditor { Ok(()) } - pub async fn get_rows(&self, row_ids: Option>) -> FlowyResult> { - match row_ids { - None => Ok(self.meta_pad.read().await.all_rows()), - Some(row_ids) => { - let rows = self.meta_pad.read().await.get_rows(row_ids)?; - Ok(rows) - } - } + pub async fn get_row_metas(&self, row_ids: Option>) -> FlowyResult>> { + let row_metas = self.meta_pad.read().await.get_rows(row_ids)?; + Ok(row_metas) + } + + pub async fn get_row_orders(&self) -> FlowyResult> { + let row_orders = self + .meta_pad + .read() + .await + .get_rows(None)? + .iter() + .map(|row_meta| RowOrder::from(row_meta)) + .collect::>(); + Ok(row_orders) } async fn modify(&self, f: F) -> FlowyResult<()> diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs index 97c322bb95..87bd7f848c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/checkbox_description.rs @@ -1,8 +1,8 @@ use crate::impl_from_and_to_type_option; -use crate::services::row::StringifyCellData; +use crate::services::row::CellDataSerde; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Field, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)] @@ -12,13 +12,13 @@ pub struct CheckboxDescription { } impl_from_and_to_type_option!(CheckboxDescription, FieldType::Checkbox); -impl StringifyCellData for CheckboxDescription { - fn str_from_cell_data(&self, data: String) -> String { +impl CellDataSerde for CheckboxDescription { + fn deserialize_cell_data(&self, data: String) -> String { data } - fn str_to_cell_data(&self, s: &str) -> Result { - let s = match string_to_bool(s) { + fn serialize_cell_data(&self, data: &str) -> Result { + let s = match string_to_bool(data) { true => "1", false => "0", }; @@ -42,19 +42,19 @@ fn string_to_bool(bool_str: &str) -> bool { #[cfg(test)] mod tests { use crate::services::cell::CheckboxDescription; - use crate::services::row::StringifyCellData; + use crate::services::row::CellDataSerde; #[test] fn checkout_box_description_test() { let description = CheckboxDescription::default(); - assert_eq!(description.str_to_cell_data("true").unwrap(), "1".to_owned()); - assert_eq!(description.str_to_cell_data("1").unwrap(), "1".to_owned()); - assert_eq!(description.str_to_cell_data("yes").unwrap(), "1".to_owned()); + assert_eq!(description.serialize_cell_data("true").unwrap(), "1".to_owned()); + assert_eq!(description.serialize_cell_data("1").unwrap(), "1".to_owned()); + assert_eq!(description.serialize_cell_data("yes").unwrap(), "1".to_owned()); - assert_eq!(description.str_to_cell_data("false").unwrap(), "0".to_owned()); - assert_eq!(description.str_to_cell_data("no").unwrap(), "0".to_owned()); - assert_eq!(description.str_to_cell_data("123").unwrap(), "0".to_owned()); + assert_eq!(description.serialize_cell_data("false").unwrap(), "0".to_owned()); + assert_eq!(description.serialize_cell_data("no").unwrap(), "0".to_owned()); + assert_eq!(description.serialize_cell_data("123").unwrap(), "0".to_owned()); - assert_eq!(description.str_from_cell_data("1".to_owned()), "1".to_owned()); + assert_eq!(description.deserialize_cell_data("1".to_owned()), "1".to_owned()); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs index 991357f63a..1b057b5314 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs @@ -1,11 +1,11 @@ use crate::impl_from_and_to_type_option; -use crate::services::row::StringifyCellData; +use crate::services::row::CellDataSerde; use chrono::format::strftime::StrftimeItems; use chrono::NaiveDateTime; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Field, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; use strum_macros::EnumIter; @@ -38,8 +38,8 @@ impl DateDescription { } } -impl StringifyCellData for DateDescription { - fn str_from_cell_data(&self, data: String) -> String { +impl CellDataSerde for DateDescription { + fn deserialize_cell_data(&self, data: String) -> String { match data.parse::() { Ok(timestamp) => { let native = NaiveDateTime::from_timestamp(timestamp, 0); @@ -52,11 +52,11 @@ impl StringifyCellData for DateDescription { } } - fn str_to_cell_data(&self, s: &str) -> Result { - let timestamp = match s.parse::() { + fn serialize_cell_data(&self, data: &str) -> Result { + let timestamp = match data.parse::() { Ok(timestamp) => timestamp, Err(e) => { - tracing::error!("Parse {} to i64 failed: {}", s, e); + tracing::error!("Parse {} to i64 failed: {}", data, e); chrono::Utc::now().timestamp() } }; @@ -149,7 +149,7 @@ impl std::default::Default for TimeFormat { #[cfg(test)] mod tests { use crate::services::cell::{DateDescription, DateFormat, TimeFormat}; - use crate::services::row::StringifyCellData; + use crate::services::row::CellDataSerde; use strum::IntoEnumIterator; #[test] @@ -167,7 +167,7 @@ mod tests { ); assert_eq!( "Mar 14,2022 17:56".to_owned(), - description.str_from_cell_data("1647251762".to_owned()) + description.deserialize_cell_data("1647251762".to_owned()) ); } DateFormat::US => { @@ -177,7 +177,7 @@ mod tests { ); assert_eq!( "2022/03/14 17:56".to_owned(), - description.str_from_cell_data("1647251762".to_owned()) + description.deserialize_cell_data("1647251762".to_owned()) ); } DateFormat::ISO => { @@ -187,7 +187,7 @@ mod tests { ); assert_eq!( "2022-03-14 17:56".to_owned(), - description.str_from_cell_data("1647251762".to_owned()) + description.deserialize_cell_data("1647251762".to_owned()) ); } DateFormat::Local => { @@ -197,7 +197,7 @@ mod tests { ); assert_eq!( "2022/03/14 17:56".to_owned(), - description.str_from_cell_data("1647251762".to_owned()) + description.deserialize_cell_data("1647251762".to_owned()) ); } } @@ -217,7 +217,7 @@ mod tests { ); assert_eq!( "Mar 14,2022 17:56".to_owned(), - description.str_from_cell_data("1647251762".to_owned()) + description.deserialize_cell_data("1647251762".to_owned()) ); } TimeFormat::TwelveHour => { @@ -227,7 +227,7 @@ mod tests { ); assert_eq!( "Mar 14,2022 05:56:02 PM".to_owned(), - description.str_from_cell_data("1647251762".to_owned()) + description.deserialize_cell_data("1647251762".to_owned()) ); } } @@ -237,6 +237,6 @@ mod tests { #[test] fn date_description_invalid_data_test() { let description = DateDescription::default(); - description.str_to_cell_data("he").unwrap(); + description.serialize_cell_data("he").unwrap(); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs index b8470280f0..a4a3c08d90 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs @@ -1,8 +1,8 @@ use crate::impl_from_and_to_type_option; -use crate::services::row::StringifyCellData; +use crate::services::row::CellDataSerde; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Field, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use lazy_static::lazy_static; use rust_decimal::prelude::Zero; use rust_decimal::Decimal; @@ -119,8 +119,8 @@ impl NumberDescription { } } -impl StringifyCellData for NumberDescription { - fn str_from_cell_data(&self, data: String) -> String { +impl CellDataSerde for NumberDescription { + fn deserialize_cell_data(&self, data: String) -> String { match self.format { NumberFormat::Number => data, NumberFormat::USD => self.money_from_str(&data, USD), @@ -129,8 +129,8 @@ impl StringifyCellData for NumberDescription { } } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(self.strip_symbol(s)) + fn serialize_cell_data(&self, data: &str) -> Result { + Ok(self.strip_symbol(data)) } } @@ -145,30 +145,42 @@ fn make_strip_symbol() -> Vec { #[cfg(test)] mod tests { use crate::services::cell::{NumberDescription, NumberFormat}; - use crate::services::row::StringifyCellData; + use crate::services::row::CellDataSerde; use strum::IntoEnumIterator; #[test] fn number_description_test() { let mut description = NumberDescription::default(); - assert_eq!(description.str_to_cell_data("¥18,443").unwrap(), "18443".to_owned()); - assert_eq!(description.str_to_cell_data("$18,443").unwrap(), "18443".to_owned()); - assert_eq!(description.str_to_cell_data("€18.443").unwrap(), "18443".to_owned()); + assert_eq!(description.serialize_cell_data("¥18,443").unwrap(), "18443".to_owned()); + assert_eq!(description.serialize_cell_data("$18,443").unwrap(), "18443".to_owned()); + assert_eq!(description.serialize_cell_data("€18.443").unwrap(), "18443".to_owned()); for format in NumberFormat::iter() { description.format = format; match format { NumberFormat::Number => { - assert_eq!(description.str_from_cell_data("18443".to_owned()), "18443".to_owned()); + assert_eq!( + description.deserialize_cell_data("18443".to_owned()), + "18443".to_owned() + ); } NumberFormat::USD => { - assert_eq!(description.str_from_cell_data("18443".to_owned()), "$18,443".to_owned()); + assert_eq!( + description.deserialize_cell_data("18443".to_owned()), + "$18,443".to_owned() + ); } NumberFormat::CNY => { - assert_eq!(description.str_from_cell_data("18443".to_owned()), "¥18,443".to_owned()); + assert_eq!( + description.deserialize_cell_data("18443".to_owned()), + "¥18,443".to_owned() + ); } NumberFormat::EUR => { - assert_eq!(description.str_from_cell_data("18443".to_owned()), "€18.443".to_owned()); + assert_eq!( + description.deserialize_cell_data("18443".to_owned()), + "€18.443".to_owned() + ); } } } @@ -183,23 +195,26 @@ mod tests { description.format = format; match format { NumberFormat::Number => { - assert_eq!(description.str_from_cell_data("18443".to_owned()), "18443".to_owned()); + assert_eq!( + description.deserialize_cell_data("18443".to_owned()), + "18443".to_owned() + ); } NumberFormat::USD => { assert_eq!( - description.str_from_cell_data("18443".to_owned()), + description.deserialize_cell_data("18443".to_owned()), "$1,844.3".to_owned() ); } NumberFormat::CNY => { assert_eq!( - description.str_from_cell_data("18443".to_owned()), + description.deserialize_cell_data("18443".to_owned()), "¥1,844.3".to_owned() ); } NumberFormat::EUR => { assert_eq!( - description.str_from_cell_data("18443".to_owned()), + description.deserialize_cell_data("18443".to_owned()), "€1.844,3".to_owned() ); } @@ -216,23 +231,26 @@ mod tests { description.format = format; match format { NumberFormat::Number => { - assert_eq!(description.str_from_cell_data("18443".to_owned()), "18443".to_owned()); + assert_eq!( + description.deserialize_cell_data("18443".to_owned()), + "18443".to_owned() + ); } NumberFormat::USD => { assert_eq!( - description.str_from_cell_data("18443".to_owned()), + description.deserialize_cell_data("18443".to_owned()), "-$18,443".to_owned() ); } NumberFormat::CNY => { assert_eq!( - description.str_from_cell_data("18443".to_owned()), + description.deserialize_cell_data("18443".to_owned()), "-¥18,443".to_owned() ); } NumberFormat::EUR => { assert_eq!( - description.str_from_cell_data("18443".to_owned()), + description.deserialize_cell_data("18443".to_owned()), "-€18.443".to_owned() ); } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs index 3a1485f31e..2f772c3c5d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs @@ -1,9 +1,9 @@ use crate::impl_from_and_to_type_option; -use crate::services::row::StringifyCellData; +use crate::services::row::CellDataSerde; use crate::services::util::*; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Field, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; // Single select @@ -17,13 +17,13 @@ pub struct SingleSelectDescription { } impl_from_and_to_type_option!(SingleSelectDescription, FieldType::SingleSelect); -impl StringifyCellData for SingleSelectDescription { - fn str_from_cell_data(&self, data: String) -> String { +impl CellDataSerde for SingleSelectDescription { + fn deserialize_cell_data(&self, data: String) -> String { data } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(select_option_id_from_data(s.to_owned(), true)) + fn serialize_cell_data(&self, data: &str) -> Result { + Ok(select_option_id_from_data(data.to_owned(), true)) } } @@ -37,13 +37,13 @@ pub struct MultiSelectDescription { pub disable_color: bool, } impl_from_and_to_type_option!(MultiSelectDescription, FieldType::MultiSelect); -impl StringifyCellData for MultiSelectDescription { - fn str_from_cell_data(&self, data: String) -> String { +impl CellDataSerde for MultiSelectDescription { + fn deserialize_cell_data(&self, data: String) -> String { data } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(select_option_id_from_data(s.to_owned(), false)) + fn serialize_cell_data(&self, data: &str) -> Result { + Ok(select_option_id_from_data(data.to_owned(), false)) } } @@ -84,14 +84,14 @@ impl SelectOption { #[cfg(test)] mod tests { use crate::services::cell::{MultiSelectDescription, SingleSelectDescription}; - use crate::services::row::StringifyCellData; + use crate::services::row::CellDataSerde; #[test] fn selection_description_test() { let description = SingleSelectDescription::default(); - assert_eq!(description.str_to_cell_data("1,2,3").unwrap(), "1".to_owned()); + assert_eq!(description.serialize_cell_data("1,2,3").unwrap(), "1".to_owned()); let description = MultiSelectDescription::default(); - assert_eq!(description.str_to_cell_data("1,2,3").unwrap(), "1,2,3".to_owned()); + assert_eq!(description.serialize_cell_data("1,2,3").unwrap(), "1,2,3".to_owned()); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs index 4c9786abb7..1f71244519 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs @@ -1,9 +1,9 @@ use crate::impl_from_and_to_type_option; -use crate::services::row::StringifyCellData; +use crate::services::row::CellDataSerde; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Field, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] @@ -13,12 +13,12 @@ pub struct RichTextDescription { } impl_from_and_to_type_option!(RichTextDescription, FieldType::RichText); -impl StringifyCellData for RichTextDescription { - fn str_from_cell_data(&self, data: String) -> String { +impl CellDataSerde for RichTextDescription { + fn deserialize_cell_data(&self, data: String) -> String { data } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(s.to_owned()) + fn serialize_cell_data(&self, data: &str) -> Result { + Ok(data.to_owned()) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index 034e7c34fb..15f5b805d9 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -1,55 +1,55 @@ -use flowy_grid_data_model::entities::{Field, FieldType}; +use flowy_grid_data_model::entities::{FieldMeta, FieldType}; pub struct FieldBuilder { - field: Field, + field_meta: FieldMeta, type_options_builder: Box, } impl FieldBuilder { pub fn new(type_options_builder: T) -> Self { - let field = Field::new("Name", "", FieldType::RichText); + let field_meta = FieldMeta::new("Name", "", FieldType::RichText); Self { - field, + field_meta, type_options_builder: Box::new(type_options_builder), } } pub fn name(mut self, name: &str) -> Self { - self.field.name = name.to_owned(); + self.field_meta.name = name.to_owned(); self } pub fn desc(mut self, desc: &str) -> Self { - self.field.desc = desc.to_owned(); + self.field_meta.desc = desc.to_owned(); self } pub fn field_type(mut self, field_type: FieldType) -> Self { - self.field.field_type = field_type; + self.field_meta.field_type = field_type; self } pub fn visibility(mut self, visibility: bool) -> Self { - self.field.visibility = visibility; + self.field_meta.visibility = visibility; self } pub fn width(mut self, width: i32) -> Self { - self.field.width = width; + self.field_meta.width = width; self } pub fn frozen(mut self, frozen: bool) -> Self { - self.field.frozen = frozen; + self.field_meta.frozen = frozen; self } - pub fn build(mut self) -> Field { - assert_eq!(self.field.field_type, self.type_options_builder.field_type()); + pub fn build(mut self) -> FieldMeta { + assert_eq!(self.field_meta.field_type, self.type_options_builder.field_type()); let type_options = self.type_options_builder.build(); - self.field.type_options = type_options; - self.field + self.field_meta.type_options = type_options; + self.field_meta } } 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 32bb2d790b..e45dad5394 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -7,7 +7,7 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - CellMetaChangeset, Field, FieldChangeset, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, + CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, }; use std::collections::HashMap; @@ -56,8 +56,8 @@ impl ClientGridEditor { })) } - pub async fn create_field(&self, field: Field) -> FlowyResult<()> { - let _ = self.modify(|grid| Ok(grid.create_field(field)?)).await?; + pub async fn create_field(&self, field_meta: FieldMeta) -> FlowyResult<()> { + let _ = self.modify(|grid| Ok(grid.create_field(field_meta)?)).await?; Ok(()) } @@ -82,9 +82,9 @@ impl ClientGridEditor { } pub async fn create_row(&self) -> FlowyResult<()> { - let fields = self.grid_meta_pad.read().await.get_fields(None)?; + let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?; let block_id = self.last_block_id().await?; - let row = row_meta_from_context(&block_id, CreateRowContextBuilder::new(&fields).build()); + let row = row_meta_from_context(&block_id, CreateRowContextBuilder::new(&field_metas).build()); let row_count = self.block_meta_manager.create_row(row).await?; let changeset = GridBlockChangeset::from_row_count(&block_id, row_count); let _ = self.update_block(changeset).await?; @@ -119,12 +119,12 @@ impl ClientGridEditor { } pub async fn get_rows(&self, row_orders: Option) -> FlowyResult> { - let row_metas = self.get_row_metas(&row_orders).await?; - let fields = self.grid_meta_pad.read().await.get_fields(None)?; + let row_metas = self.get_row_metas(row_orders.as_ref()).await?; + let field_meta = self.grid_meta_pad.read().await.get_field_metas(None)?; match row_orders { - None => Ok(make_rows(&fields, row_metas)), + None => Ok(make_rows(&field_meta, row_metas)), Some(row_orders) => { - let mut row_map: HashMap = make_row_by_row_id(&fields, row_metas); + let mut row_map: HashMap = make_row_by_row_id(&field_meta, row_metas); let rows = row_orders .iter() .flat_map(|row_order| row_map.remove(&row_order.row_id)) @@ -134,7 +134,7 @@ impl ClientGridEditor { } } - pub async fn get_row_metas(&self, row_orders: &Option) -> FlowyResult> { + pub async fn get_row_metas(&self, row_orders: Option<&RepeatedRowOrder>) -> FlowyResult>> { match row_orders { None => { let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); @@ -156,13 +156,20 @@ impl ClientGridEditor { Ok(()) } - pub async fn grid_data(&self) -> Grid { - todo!() + pub async fn grid_data(&self) -> FlowyResult { + let field_orders = self.grid_meta_pad.read().await.get_field_orders(); + let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); + let row_orders = self.block_meta_manager.get_row_orders(grid_blocks).await?; + Ok(Grid { + id: self.grid_id.clone(), + field_orders, + row_orders, + }) } - pub async fn get_fields(&self, field_orders: Option) -> FlowyResult> { - let fields = self.grid_meta_pad.read().await.get_fields(field_orders)?; - Ok(fields) + pub async fn get_field_metas(&self, field_orders: Option) -> FlowyResult> { + let field_meta = self.grid_meta_pad.read().await.get_field_metas(field_orders)?; + Ok(field_meta) } pub async fn get_blocks(&self) -> FlowyResult> { diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs new file mode 100644 index 0000000000..148b5254ba --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs @@ -0,0 +1,32 @@ +use crate::services::cell::*; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{FieldMeta, FieldType}; + +pub trait CellDataSerde { + fn deserialize_cell_data(&self, data: String) -> String; + fn serialize_cell_data(&self, data: &str) -> Result; +} + +#[allow(dead_code)] +pub fn serialize_cell_data(data: &str, field: &FieldMeta) -> Result { + match field.field_type { + FieldType::RichText => RichTextDescription::from(field).serialize_cell_data(data), + FieldType::Number => NumberDescription::from(field).serialize_cell_data(data), + FieldType::DateTime => DateDescription::from(field).serialize_cell_data(data), + FieldType::SingleSelect => SingleSelectDescription::from(field).serialize_cell_data(data), + FieldType::MultiSelect => MultiSelectDescription::from(field).serialize_cell_data(data), + FieldType::Checkbox => CheckboxDescription::from(field).serialize_cell_data(data), + } +} + +pub fn deserialize_cell_data(data: String, field: &FieldMeta) -> Result { + let s = match field.field_type { + FieldType::RichText => RichTextDescription::from(field).deserialize_cell_data(data), + FieldType::Number => NumberDescription::from(field).deserialize_cell_data(data), + FieldType::DateTime => DateDescription::from(field).deserialize_cell_data(data), + FieldType::SingleSelect => SingleSelectDescription::from(field).deserialize_cell_data(data), + FieldType::MultiSelect => MultiSelectDescription::from(field).deserialize_cell_data(data), + FieldType::Checkbox => CheckboxDescription::from(field).deserialize_cell_data(data), + }; + Ok(s) +} diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs deleted file mode 100644 index 3a49d5f7e2..0000000000 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs +++ /dev/null @@ -1,33 +0,0 @@ -use crate::services::cell::*; -use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{Field, FieldType}; - -pub trait StringifyCellData { - fn str_from_cell_data(&self, data: String) -> String; - fn str_to_cell_data(&self, s: &str) -> Result; -} - -#[allow(dead_code)] -pub fn stringify_serialize(field: &Field, s: &str) -> Result { - match field.field_type { - FieldType::RichText => RichTextDescription::from(field).str_to_cell_data(s), - FieldType::Number => NumberDescription::from(field).str_to_cell_data(s), - FieldType::DateTime => DateDescription::from(field).str_to_cell_data(s), - FieldType::SingleSelect => SingleSelectDescription::from(field).str_to_cell_data(s), - FieldType::MultiSelect => MultiSelectDescription::from(field).str_to_cell_data(s), - FieldType::Checkbox => CheckboxDescription::from(field).str_to_cell_data(s), - } -} - -pub(crate) fn stringify_deserialize(data: String, field: &Field) -> Result { - // let _ = check_type_id(&data, field)?; - let s = match field.field_type { - FieldType::RichText => RichTextDescription::from(field).str_from_cell_data(data), - FieldType::Number => NumberDescription::from(field).str_from_cell_data(data), - FieldType::DateTime => DateDescription::from(field).str_from_cell_data(data), - FieldType::SingleSelect => SingleSelectDescription::from(field).str_from_cell_data(data), - FieldType::MultiSelect => MultiSelectDescription::from(field).str_from_cell_data(data), - FieldType::Checkbox => CheckboxDescription::from(field).str_from_cell_data(data), - }; - Ok(s) -} diff --git a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs index 993e3401e3..fec4ea8d8c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs @@ -1,7 +1,7 @@ -mod cell_stringify; +mod cell_data_serde; mod row_builder; mod row_loader; -pub use cell_stringify::*; +pub use cell_data_serde::*; pub use row_builder::*; pub(crate) use row_loader::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index 7414c3ba8b..6bc231293a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -1,14 +1,14 @@ -use flowy_grid_data_model::entities::{CellMeta, Field, RowMeta, DEFAULT_ROW_HEIGHT}; +use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT}; use std::collections::HashMap; pub struct CreateRowContextBuilder<'a> { #[allow(dead_code)] - fields: &'a [Field], + fields: &'a [FieldMeta], ctx: CreateRowContext, } impl<'a> CreateRowContextBuilder<'a> { - pub fn new(fields: &'a [Field]) -> Self { + pub fn new(fields: &'a [FieldMeta]) -> Self { let ctx = CreateRowContext { row_id: uuid::Uuid::new_v4().to_string(), cell_by_field_id: Default::default(), 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 6f7640fb1e..aa114c3d07 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 @@ -1,7 +1,8 @@ -use crate::services::row::stringify_deserialize; -use flowy_grid_data_model::entities::{Cell, CellMeta, Field, Row, RowMeta, RowOrder}; +use crate::services::row::deserialize_cell_data; +use flowy_grid_data_model::entities::{Cell, CellMeta, FieldMeta, Row, RowMeta, RowOrder}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; +use std::sync::Arc; pub(crate) struct RowIdsPerBlock { pub(crate) block_id: String, @@ -21,15 +22,16 @@ pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec>() } -pub(crate) fn make_rows(fields: &[Field], row_metas: Vec) -> Vec { +pub(crate) fn make_rows(fields: &[FieldMeta], row_metas: Vec>) -> Vec { let field_map = fields .iter() .map(|field| (&field.id, field)) - .collect::>(); + .collect::>(); - let make_row = |row_meta: RowMeta| { + let make_row = |row_meta: Arc| { let cell_by_field_id = row_meta .cell_by_field_id + .clone() .into_par_iter() .flat_map(|(field_id, raw_cell)| make_cell(&field_map, field_id, raw_cell)) .collect::>(); @@ -45,9 +47,9 @@ pub(crate) fn make_rows(fields: &[Field], row_metas: Vec) -> Vec { } #[inline(always)] -fn make_cell(field_map: &HashMap<&String, &Field>, field_id: String, raw_cell: CellMeta) -> Option<(String, Cell)> { - let field = field_map.get(&field_id)?; - match stringify_deserialize(raw_cell.data, field) { +fn make_cell(field_map: &HashMap<&String, &FieldMeta>, field_id: String, raw_cell: CellMeta) -> Option<(String, Cell)> { + let field_meta = field_map.get(&field_id)?; + match deserialize_cell_data(raw_cell.data, field_meta) { Ok(content) => { let cell = Cell::new(&field_id, content); Some((field_id, cell)) @@ -59,15 +61,16 @@ fn make_cell(field_map: &HashMap<&String, &Field>, field_id: String, raw_cell: C } } -pub(crate) fn make_row_by_row_id(fields: &[Field], row_metas: Vec) -> HashMap { +pub(crate) fn make_row_by_row_id(fields: &[FieldMeta], row_metas: Vec>) -> HashMap { let field_map = fields .iter() .map(|field| (&field.id, field)) - .collect::>(); + .collect::>(); - let make_row = |row_meta: RowMeta| { + let make_row = |row_meta: Arc| { let cell_by_field_id = row_meta .cell_by_field_id + .clone() .into_par_iter() .flat_map(|(field_id, raw_cell)| make_cell(&field_map, field_id, raw_cell)) .collect::>(); 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 360407b3b8..910589eb53 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -1,7 +1,7 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; use flowy_grid::services::cell::*; -use flowy_grid::services::row::{CreateRowContextBuilder, StringifyCellData}; +use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, CreateRowContextBuilder}; use flowy_grid_data_model::entities::{FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMetaChangeset}; #[tokio::test] @@ -17,19 +17,19 @@ async fn grid_create_field() { let scripts = vec![ AssertFieldCount(2), CreateField { - field: text_field.clone(), + field_meta: text_field.clone(), }, AssertFieldEqual { field_index: 2, - field: text_field, + field_meta: text_field, }, AssertFieldCount(3), CreateField { - field: single_select_field.clone(), + field_meta: single_select_field.clone(), }, AssertFieldEqual { field_index: 3, - field: single_select_field, + field_meta: single_select_field, }, AssertFieldCount(4), ]; @@ -42,11 +42,11 @@ async fn grid_create_duplicate_field() { let scripts = vec![ AssertFieldCount(2), CreateField { - field: text_field.clone(), + field_meta: text_field.clone(), }, AssertFieldCount(3), CreateField { - field: text_field.clone(), + field_meta: text_field.clone(), }, AssertFieldCount(3), ]; @@ -69,12 +69,12 @@ async fn grid_update_field_with_empty_change() { let scripts = vec![ CreateField { - field: single_select_field.clone(), + field_meta: single_select_field.clone(), }, UpdateField { changeset }, AssertFieldEqual { field_index: 2, - field: single_select_field, + field_meta: single_select_field, }, ]; GridEditorTest::new().await.run_scripts(scripts).await; @@ -105,12 +105,12 @@ async fn grid_update_field() { let scripts = vec![ CreateField { - field: single_select_field.clone(), + field_meta: single_select_field.clone(), }, UpdateField { changeset }, AssertFieldEqual { field_index: 2, - field: cloned_field, + field_meta: cloned_field, }, AssertGridMetaPad, ]; @@ -122,10 +122,10 @@ async fn grid_delete_field() { let text_field = create_text_field(); let scripts = vec![ CreateField { - field: text_field.clone(), + field_meta: text_field.clone(), }, AssertFieldCount(3), - DeleteField { field: text_field }, + DeleteField { field_meta: text_field }, AssertFieldCount(2), ]; GridEditorTest::new().await.run_scripts(scripts).await; @@ -177,7 +177,7 @@ async fn grid_create_row() { #[tokio::test] async fn grid_create_row2() { let mut test = GridEditorTest::new().await; - let create_row_context = CreateRowContextBuilder::new(&test.fields).build(); + let create_row_context = CreateRowContextBuilder::new(&test.field_metas).build(); let scripts = vec![ AssertRowCount(3), CreateRow { @@ -191,7 +191,7 @@ async fn grid_create_row2() { #[tokio::test] async fn grid_update_row() { let mut test = GridEditorTest::new().await; - let context = CreateRowContextBuilder::new(&test.fields).build(); + let context = CreateRowContextBuilder::new(&test.field_metas).build(); let changeset = RowMetaChangeset { row_id: context.row_id.clone(), height: None, @@ -214,8 +214,8 @@ async fn grid_update_row() { #[tokio::test] async fn grid_delete_row() { let mut test = GridEditorTest::new().await; - let context_1 = CreateRowContextBuilder::new(&test.fields).build(); - let context_2 = CreateRowContextBuilder::new(&test.fields).build(); + let context_1 = CreateRowContextBuilder::new(&test.field_metas).build(); + let context_2 = CreateRowContextBuilder::new(&test.field_metas).build(); let row_ids = vec![context_1.row_id.clone(), context_2.row_id.clone()]; let scripts = vec![ AssertRowCount(3), @@ -240,26 +240,26 @@ async fn grid_delete_row() { #[tokio::test] async fn grid_update_cell() { let mut test = GridEditorTest::new().await; - let mut builder = CreateRowContextBuilder::new(&test.fields); - for field in &test.fields { + let mut builder = CreateRowContextBuilder::new(&test.field_metas); + for field in &test.field_metas { match field.field_type { FieldType::RichText => { - builder = builder.add_cell(&field.id, "hello world".to_owned()); + let data = serialize_cell_data("hello world", field).unwrap(); + builder = builder.add_cell(&field.id, data); } FieldType::Number => { - let description = NumberDescription::from(field); - let data = description.str_to_cell_data("¥18,443").unwrap(); + let data = serialize_cell_data("¥18,443", field).unwrap(); builder = builder.add_cell(&field.id, data); } FieldType::DateTime => { - let description = DateDescription::from(field); - let data = description.str_to_cell_data("1647251762").unwrap(); + let data = serialize_cell_data("1647251762", field).unwrap(); builder = builder.add_cell(&field.id, data); } FieldType::SingleSelect => { let description = SingleSelectDescription::from(field); let options = description.options.first().unwrap(); - let data = description.str_to_cell_data(&options.id).unwrap(); + + let data = description.serialize_cell_data(&options.id).unwrap(); builder = builder.add_cell(&field.id, data); } FieldType::MultiSelect => { @@ -270,12 +270,11 @@ async fn grid_update_cell() { .map(|option| option.id.clone()) .collect::>() .join(","); - let data = description.str_to_cell_data(&options).unwrap(); + let data = description.serialize_cell_data(&options).unwrap(); builder = builder.add_cell(&field.id, data); } FieldType::Checkbox => { - let description = CheckboxDescription::from(field); - let data = description.str_to_cell_data("false").unwrap(); + let data = serialize_cell_data("false", field).unwrap(); builder = builder.add_cell(&field.id, data); } } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index f123ecc9ed..777bad2949 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -3,7 +3,7 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::row::CreateRowContext; use flowy_grid_data_model::entities::{ - CellMetaChangeset, Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMeta, RowMetaChangeset, + CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlock, GridBlockChangeset, RowMeta, RowMetaChangeset, }; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::helper::ViewTest; @@ -14,18 +14,18 @@ use tokio::time::sleep; pub enum EditorScript { CreateField { - field: Field, + field_meta: FieldMeta, }, UpdateField { changeset: FieldChangeset, }, DeleteField { - field: Field, + field_meta: FieldMeta, }, AssertFieldCount(usize), AssertFieldEqual { field_index: usize, - field: Field, + field_meta: FieldMeta, }, CreateBlock { block: GridBlock, @@ -68,27 +68,31 @@ pub struct GridEditorTest { pub sdk: FlowySDKTest, pub grid_id: String, pub editor: Arc, - pub fields: Vec, + pub field_metas: Vec, pub grid_blocks: Vec, - pub row_metas: Vec, + pub row_metas: Vec>, } impl GridEditorTest { pub async fn new() -> Self { + Self::with_data("".to_owned()).await + } + + pub async fn with_data(data: String) -> Self { let sdk = FlowySDKTest::default(); let _ = sdk.init_user().await; - let test = ViewTest::new_grid_view(&sdk).await; + let test = ViewTest::new_grid_view(&sdk, data).await; let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); - let fields = editor.get_fields(None).await.unwrap(); + let fields = editor.get_field_metas(None).await.unwrap(); let grid_blocks = editor.get_blocks().await.unwrap(); - let row_metas = editor.get_row_metas(&None).await.unwrap(); + let row_metas = editor.get_row_metas(None).await.unwrap(); let grid_id = test.view.id; Self { sdk, grid_id, editor, - fields, + field_metas: fields, grid_blocks, row_metas, } @@ -107,26 +111,28 @@ impl GridEditorTest { let _cache = rev_manager.revision_cache().await; match script { - EditorScript::CreateField { field } => { + EditorScript::CreateField { field_meta: field } => { self.editor.create_field(field).await.unwrap(); - self.fields = self.editor.get_fields(None).await.unwrap(); + self.field_metas = self.editor.get_field_metas(None).await.unwrap(); } EditorScript::UpdateField { changeset: change } => { self.editor.update_field(change).await.unwrap(); - self.fields = self.editor.get_fields(None).await.unwrap(); + self.field_metas = self.editor.get_field_metas(None).await.unwrap(); } - EditorScript::DeleteField { field } => { + EditorScript::DeleteField { field_meta: field } => { self.editor.delete_field(&field.id).await.unwrap(); - self.fields = self.editor.get_fields(None).await.unwrap(); + self.field_metas = self.editor.get_field_metas(None).await.unwrap(); } EditorScript::AssertFieldCount(count) => { - assert_eq!(self.editor.get_fields(None).await.unwrap().len(), count); + assert_eq!(self.editor.get_field_metas(None).await.unwrap().len(), count); } - EditorScript::AssertFieldEqual { field_index, field } => { - let repeated_fields = self.editor.get_fields(None).await.unwrap(); - let compared_field = repeated_fields[field_index].clone(); - assert_eq!(compared_field, field); + EditorScript::AssertFieldEqual { + field_index, + field_meta, + } => { + let field_metas = self.editor.get_field_metas(None).await.unwrap(); + assert_eq!(field_metas[field_index].clone(), field_meta); } EditorScript::CreateBlock { block } => { self.editor.create_block(block).await.unwrap(); @@ -153,18 +159,18 @@ impl GridEditorTest { } EditorScript::CreateEmptyRow => { self.editor.create_row().await.unwrap(); - self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); + self.row_metas = self.editor.get_row_metas(None).await.unwrap(); self.grid_blocks = self.editor.get_blocks().await.unwrap(); } EditorScript::CreateRow { context } => { self.editor.insert_rows(vec![context]).await.unwrap(); - self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); + self.row_metas = self.editor.get_row_metas(None).await.unwrap(); self.grid_blocks = self.editor.get_blocks().await.unwrap(); } EditorScript::UpdateRow { changeset: change } => self.editor.update_row(change).await.unwrap(), EditorScript::DeleteRow { row_ids } => { self.editor.delete_rows(row_ids).await.unwrap(); - self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); + self.row_metas = self.editor.get_row_metas(None).await.unwrap(); self.grid_blocks = self.editor.get_blocks().await.unwrap(); } EditorScript::AssertRow { changeset } => { @@ -180,7 +186,7 @@ impl GridEditorTest { } EditorScript::UpdateCell { changeset } => { self.editor.update_cell(changeset).await.unwrap(); - self.row_metas = self.editor.get_row_metas(&None).await.unwrap(); + self.row_metas = self.editor.get_row_metas(None).await.unwrap(); } EditorScript::AssertRowCount(count) => { assert_eq!(self.editor.get_rows(None).await.unwrap().len(), count); @@ -195,7 +201,7 @@ impl GridEditorTest { } } -pub fn create_text_field() -> Field { +pub fn create_text_field() -> FieldMeta { FieldBuilder::new(RichTextTypeOptionsBuilder::default()) .name("Name") .visibility(true) @@ -203,7 +209,7 @@ pub fn create_text_field() -> Field { .build() } -pub fn create_single_select_field() -> Field { +pub fn create_single_select_field() -> FieldMeta { let single_select = SingleSelectTypeOptionsBuilder::default() .option(SelectOption::new("Done")) .option(SelectOption::new("Progress")); diff --git a/frontend/rust-lib/flowy-net/src/local_server/server.rs b/frontend/rust-lib/flowy-net/src/local_server/server.rs index 646ca04e0f..6bcd538a6b 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/server.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/server.rs @@ -308,7 +308,7 @@ impl FolderCouldServiceV1 for LocalServer { belongings: RepeatedView::default(), modified_time: time, create_time: time, - ext_data: params.ext_data, + ext_data: "".to_string(), thumbnail: params.thumbnail, plugin_type: params.plugin_type, }; diff --git a/frontend/rust-lib/flowy-test/src/helper.rs b/frontend/rust-lib/flowy-test/src/helper.rs index 9c03c09bb5..03c4077831 100644 --- a/frontend/rust-lib/flowy-test/src/helper.rs +++ b/frontend/rust-lib/flowy-test/src/helper.rs @@ -26,11 +26,11 @@ pub struct ViewTest { impl ViewTest { #[allow(dead_code)] - pub async fn new(sdk: &FlowySDKTest, data_type: ViewDataType) -> Self { + pub async fn new(sdk: &FlowySDKTest, data_type: ViewDataType, data: String) -> Self { let workspace = create_workspace(sdk, "Workspace", "").await; open_workspace(sdk, &workspace.id).await; let app = create_app(sdk, "App", "AppFlowy GitHub Project", &workspace.id).await; - let view = create_view(sdk, &app.id, data_type).await; + let view = create_view(sdk, &app.id, data_type, data).await; Self { sdk: sdk.clone(), workspace, @@ -39,14 +39,12 @@ impl ViewTest { } } - #[allow(dead_code)] - pub async fn new_grid_view(sdk: &FlowySDKTest) -> Self { - Self::new(sdk, ViewDataType::Grid).await + pub async fn new_grid_view(sdk: &FlowySDKTest, data: String) -> Self { + Self::new(sdk, ViewDataType::Grid, data).await } - #[allow(dead_code)] pub async fn new_text_block_view(sdk: &FlowySDKTest) -> Self { - Self::new(sdk, ViewDataType::TextBlock).await + Self::new(sdk, ViewDataType::TextBlock, "".to_owned()).await } } @@ -93,15 +91,15 @@ async fn create_app(sdk: &FlowySDKTest, name: &str, desc: &str, workspace_id: &s app } -async fn create_view(sdk: &FlowySDKTest, app_id: &str, data_type: ViewDataType) -> View { +async fn create_view(sdk: &FlowySDKTest, app_id: &str, data_type: ViewDataType, data: String) -> View { let request = CreateViewPayload { belong_to_id: app_id.to_string(), name: "View A".to_string(), desc: "".to_string(), thumbnail: Some("http://1.png".to_string()), data_type, - ext_data: "".to_string(), plugin_type: 0, + data, }; let view = FolderEventBuilder::new(sdk.clone()) diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index 790f9f3cfa..bd8379845a 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -50,27 +50,28 @@ impl GridBlockMetaPad { }) } - pub fn get_rows(&self, row_ids: Vec) -> CollaborateResult> { - let row_map = self - .rows - .iter() - .map(|row| (&row.id, row.clone())) - .collect::>>(); + pub fn get_rows(&self, row_ids: Option>) -> CollaborateResult>> { + match row_ids { + None => Ok(self.rows.iter().map(|row| row.clone()).collect::>()), + Some(row_ids) => { + let row_map = self + .rows + .iter() + .map(|row| (&row.id, row.clone())) + .collect::>>(); - Ok(row_ids - .iter() - .flat_map(|row_id| match row_map.get(row_id) { - None => { - tracing::error!("Can't find the row with id: {}", row_id); - None - } - Some(row) => Some((**row).clone()), - }) - .collect::>()) - } - - pub fn all_rows(&self) -> Vec { - self.rows.iter().map(|row| (**row).clone()).collect::>() + Ok(row_ids + .iter() + .flat_map(|row_id| match row_map.get(row_id) { + None => { + tracing::error!("Can't find the row with id: {}", row_id); + None + } + Some(row) => Some(row.clone()), + }) + .collect::>()) + } + } } pub fn number_of_rows(&self) -> i32 { diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index 5fe63ca7d1..cbf31463a4 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -1,10 +1,10 @@ use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBlockMetaDelta, GridMetaDelta}; use crate::errors::{CollaborateError, CollaborateResult}; -use flowy_grid_data_model::entities::{Field, GridBlock, GridBlockMeta, GridMeta, RowMeta}; +use flowy_grid_data_model::entities::{FieldMeta, GridBlock, GridBlockMeta, GridMeta, RowMeta}; pub struct GridBuilder { grid_id: String, - fields: Vec, + fields: Vec, grid_block: GridBlock, grid_block_meta: GridBlockMeta, } @@ -25,7 +25,7 @@ impl GridBuilder { } } - pub fn add_field(mut self, field: Field) -> Self { + pub fn add_field(mut self, field: FieldMeta) -> Self { self.fields.push(field); self } @@ -62,7 +62,7 @@ pub struct BuildGridInfo { } #[allow(dead_code)] -fn check_rows(fields: &[Field], rows: &[RowMeta]) -> CollaborateResult<()> { +fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> { let field_ids = fields.iter().map(|field| &field.id).collect::>(); for row in rows { let cell_field_ids = row.cell_by_field_id.keys().into_iter().collect::>(); @@ -77,13 +77,13 @@ fn check_rows(fields: &[Field], rows: &[RowMeta]) -> CollaborateResult<()> { #[cfg(test)] mod tests { use crate::client_grid::GridBuilder; - use flowy_grid_data_model::entities::{Field, FieldType, GridBlockMeta, GridMeta}; + use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMeta, GridMeta}; #[test] fn create_default_grid_test() { let info = GridBuilder::new("1") - .add_field(Field::new("Name", "", FieldType::RichText)) - .add_field(Field::new("Tags", "", FieldType::SingleSelect)) + .add_field(FieldMeta::new("Name", "", FieldType::RichText)) + .add_field(FieldMeta::new("Tags", "", FieldType::SingleSelect)) .add_empty_row() .add_empty_row() .add_empty_row() diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index d7c9f13928..f303990546 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -2,7 +2,7 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use flowy_grid_data_model::entities::{ - Field, FieldChangeset, GridBlock, GridBlockChangeset, GridMeta, RepeatedFieldOrder, + FieldChangeset, FieldMeta, FieldOrder, GridBlock, GridBlockChangeset, GridMeta, RepeatedFieldOrder, }; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; @@ -34,13 +34,13 @@ impl GridMetaPad { Self::from_delta(grid_delta) } - pub fn create_field(&mut self, field: Field) -> CollaborateResult> { + pub fn create_field(&mut self, field_meta: FieldMeta) -> CollaborateResult> { self.modify_grid(|grid| { - if grid.fields.contains(&field) { + if grid.fields.contains(&field_meta) { tracing::warn!("Duplicate grid field"); Ok(None) } else { - grid.fields.push(field); + grid.fields.push(field_meta); Ok(Some(())) } }) @@ -56,7 +56,15 @@ impl GridMetaPad { }) } - pub fn get_fields(&self, field_orders: Option) -> CollaborateResult> { + pub fn get_field_orders(&self) -> Vec { + self.grid_meta + .fields + .iter() + .map(|field_meta| FieldOrder::from(field_meta)) + .collect() + } + + pub fn get_field_metas(&self, field_orders: Option) -> CollaborateResult> { match field_orders { None => Ok(self.grid_meta.fields.clone()), Some(field_orders) => { @@ -65,7 +73,7 @@ impl GridMetaPad { .fields .iter() .map(|field| (&field.id, field)) - .collect::>(); + .collect::>(); let fields = field_orders .iter() @@ -76,7 +84,7 @@ impl GridMetaPad { } Some(field) => Some((*field).clone()), }) - .collect::>(); + .collect::>(); Ok(fields) } } @@ -131,7 +139,18 @@ impl GridMetaPad { tracing::warn!("Duplicate grid block"); Ok(None) } else { - grid.blocks.push(block); + match grid.blocks.last() { + None => grid.blocks.push(block), + Some(last_block) => { + if last_block.start_row_index > block.start_row_index + && last_block.len() > block.start_row_index + { + let msg = format!("GridBlock's start_row_index should be greater than the last_block's start_row_index and its len"); + return Err(CollaborateError::internal().context(msg)) + } + grid.blocks.push(block); + } + } Ok(Some(())) } }) @@ -168,7 +187,7 @@ impl GridMetaPad { self.delta.to_delta_str() } - pub fn fields(&self) -> &[Field] { + pub fn fields(&self) -> &[FieldMeta] { &self.grid_meta.fields } @@ -208,7 +227,7 @@ impl GridMetaPad { pub fn modify_field(&mut self, field_id: &str, f: F) -> CollaborateResult> where - F: FnOnce(&mut Field) -> CollaborateResult>, + F: FnOnce(&mut FieldMeta) -> CollaborateResult>, { self.modify_grid(|grid| match grid.fields.iter().position(|field| field.id == field_id) { None => { diff --git a/shared-lib/flowy-folder-data-model/src/entities/view.rs b/shared-lib/flowy-folder-data-model/src/entities/view.rs index 8d6ac05406..bf7b99866c 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/view.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/view.rs @@ -124,10 +124,10 @@ pub struct CreateViewPayload { pub data_type: ViewDataType, #[pb(index = 6)] - pub ext_data: String, + pub plugin_type: i32, #[pb(index = 7)] - pub plugin_type: i32, + pub data: String, } #[derive(Default, ProtoBuf, Debug, Clone)] @@ -148,15 +148,12 @@ pub struct CreateViewParams { pub data_type: ViewDataType, #[pb(index = 6)] - pub ext_data: String, - - #[pb(index = 7)] pub view_id: String, - #[pb(index = 8)] + #[pb(index = 7)] pub data: String, - #[pb(index = 9)] + #[pb(index = 8)] pub plugin_type: i32, } @@ -167,12 +164,10 @@ impl TryInto for CreateViewPayload { let name = ViewName::parse(self.name)?.0; let belong_to_id = AppIdentify::parse(self.belong_to_id)?.0; let view_id = uuid::Uuid::new_v4().to_string(); - let ext_data = ViewExtensionData::parse(self.ext_data)?.0; let thumbnail = match self.thumbnail { None => "".to_string(), Some(thumbnail) => ViewThumbnail::parse(thumbnail)?.0, }; - let data = "".to_string(); Ok(CreateViewParams { belong_to_id, @@ -180,9 +175,8 @@ impl TryInto for CreateViewPayload { desc: self.desc, data_type: self.data_type, thumbnail, - ext_data, view_id, - data, + data: self.data, plugin_type: self.plugin_type, }) } diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs index bb38b794f2..15d8e2feaa 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs +++ b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs @@ -793,8 +793,8 @@ pub struct CreateViewPayload { pub name: ::std::string::String, pub desc: ::std::string::String, pub data_type: ViewDataType, - pub ext_data: ::std::string::String, pub plugin_type: i32, + pub data: ::std::string::String, // message oneof groups pub one_of_thumbnail: ::std::option::Option, // special fields @@ -960,33 +960,7 @@ impl CreateViewPayload { self.data_type = v; } - // string ext_data = 6; - - - pub fn get_ext_data(&self) -> &str { - &self.ext_data - } - pub fn clear_ext_data(&mut self) { - self.ext_data.clear(); - } - - // Param is passed by value, moved - pub fn set_ext_data(&mut self, v: ::std::string::String) { - self.ext_data = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_ext_data(&mut self) -> &mut ::std::string::String { - &mut self.ext_data - } - - // Take field - pub fn take_ext_data(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.ext_data, ::std::string::String::new()) - } - - // int32 plugin_type = 7; + // int32 plugin_type = 6; pub fn get_plugin_type(&self) -> i32 { @@ -1000,6 +974,32 @@ impl CreateViewPayload { pub fn set_plugin_type(&mut self, v: i32) { self.plugin_type = v; } + + // string data = 7; + + + pub fn get_data(&self) -> &str { + &self.data + } + pub fn clear_data(&mut self) { + self.data.clear(); + } + + // Param is passed by value, moved + pub fn set_data(&mut self, v: ::std::string::String) { + 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 { + &mut self.data + } + + // Take field + pub fn take_data(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.data, ::std::string::String::new()) + } } impl ::protobuf::Message for CreateViewPayload { @@ -1030,15 +1030,15 @@ impl ::protobuf::Message for CreateViewPayload { ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.data_type, 5, &mut self.unknown_fields)? }, 6 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.ext_data)?; - }, - 7 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } let tmp = is.read_int32()?; self.plugin_type = tmp; }, + 7 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -1063,11 +1063,11 @@ impl ::protobuf::Message for CreateViewPayload { if self.data_type != ViewDataType::TextBlock { my_size += ::protobuf::rt::enum_size(5, self.data_type); } - if !self.ext_data.is_empty() { - my_size += ::protobuf::rt::string_size(6, &self.ext_data); - } if self.plugin_type != 0 { - my_size += ::protobuf::rt::value_size(7, self.plugin_type, ::protobuf::wire_format::WireTypeVarint); + my_size += ::protobuf::rt::value_size(6, self.plugin_type, ::protobuf::wire_format::WireTypeVarint); + } + if !self.data.is_empty() { + my_size += ::protobuf::rt::string_size(7, &self.data); } if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail { match v { @@ -1094,11 +1094,11 @@ impl ::protobuf::Message for CreateViewPayload { if self.data_type != ViewDataType::TextBlock { os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?; } - if !self.ext_data.is_empty() { - os.write_string(6, &self.ext_data)?; - } if self.plugin_type != 0 { - os.write_int32(7, self.plugin_type)?; + os.write_int32(6, self.plugin_type)?; + } + if !self.data.is_empty() { + os.write_string(7, &self.data)?; } if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail { match v { @@ -1170,16 +1170,16 @@ impl ::protobuf::Message for CreateViewPayload { |m: &CreateViewPayload| { &m.data_type }, |m: &mut CreateViewPayload| { &mut m.data_type }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "ext_data", - |m: &CreateViewPayload| { &m.ext_data }, - |m: &mut CreateViewPayload| { &mut m.ext_data }, - )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( "plugin_type", |m: &CreateViewPayload| { &m.plugin_type }, |m: &mut CreateViewPayload| { &mut m.plugin_type }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "data", + |m: &CreateViewPayload| { &m.data }, + |m: &mut CreateViewPayload| { &mut m.data }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "CreateViewPayload", fields, @@ -1201,8 +1201,8 @@ impl ::protobuf::Clear for CreateViewPayload { self.desc.clear(); self.one_of_thumbnail = ::std::option::Option::None; self.data_type = ViewDataType::TextBlock; - self.ext_data.clear(); self.plugin_type = 0; + self.data.clear(); self.unknown_fields.clear(); } } @@ -1227,7 +1227,6 @@ pub struct CreateViewParams { pub desc: ::std::string::String, pub thumbnail: ::std::string::String, pub data_type: ViewDataType, - pub ext_data: ::std::string::String, pub view_id: ::std::string::String, pub data: ::std::string::String, pub plugin_type: i32, @@ -1366,33 +1365,7 @@ impl CreateViewParams { self.data_type = v; } - // string ext_data = 6; - - - pub fn get_ext_data(&self) -> &str { - &self.ext_data - } - pub fn clear_ext_data(&mut self) { - self.ext_data.clear(); - } - - // Param is passed by value, moved - pub fn set_ext_data(&mut self, v: ::std::string::String) { - self.ext_data = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_ext_data(&mut self) -> &mut ::std::string::String { - &mut self.ext_data - } - - // Take field - pub fn take_ext_data(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.ext_data, ::std::string::String::new()) - } - - // string view_id = 7; + // string view_id = 6; pub fn get_view_id(&self) -> &str { @@ -1418,7 +1391,7 @@ impl CreateViewParams { ::std::mem::replace(&mut self.view_id, ::std::string::String::new()) } - // string data = 8; + // string data = 7; pub fn get_data(&self) -> &str { @@ -1444,7 +1417,7 @@ impl CreateViewParams { ::std::mem::replace(&mut self.data, ::std::string::String::new()) } - // int32 plugin_type = 9; + // int32 plugin_type = 8; pub fn get_plugin_type(&self) -> i32 { @@ -1485,15 +1458,12 @@ impl ::protobuf::Message for CreateViewParams { ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.data_type, 5, &mut self.unknown_fields)? }, 6 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.ext_data)?; - }, - 7 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.view_id)?; }, - 8 => { + 7 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; }, - 9 => { + 8 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } @@ -1527,17 +1497,14 @@ impl ::protobuf::Message for CreateViewParams { if self.data_type != ViewDataType::TextBlock { my_size += ::protobuf::rt::enum_size(5, self.data_type); } - if !self.ext_data.is_empty() { - my_size += ::protobuf::rt::string_size(6, &self.ext_data); - } if !self.view_id.is_empty() { - my_size += ::protobuf::rt::string_size(7, &self.view_id); + my_size += ::protobuf::rt::string_size(6, &self.view_id); } if !self.data.is_empty() { - my_size += ::protobuf::rt::string_size(8, &self.data); + my_size += ::protobuf::rt::string_size(7, &self.data); } if self.plugin_type != 0 { - my_size += ::protobuf::rt::value_size(9, self.plugin_type, ::protobuf::wire_format::WireTypeVarint); + my_size += ::protobuf::rt::value_size(8, self.plugin_type, ::protobuf::wire_format::WireTypeVarint); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -1560,17 +1527,14 @@ impl ::protobuf::Message for CreateViewParams { if self.data_type != ViewDataType::TextBlock { os.write_enum(5, ::protobuf::ProtobufEnum::value(&self.data_type))?; } - if !self.ext_data.is_empty() { - os.write_string(6, &self.ext_data)?; - } if !self.view_id.is_empty() { - os.write_string(7, &self.view_id)?; + os.write_string(6, &self.view_id)?; } if !self.data.is_empty() { - os.write_string(8, &self.data)?; + os.write_string(7, &self.data)?; } if self.plugin_type != 0 { - os.write_int32(9, self.plugin_type)?; + os.write_int32(8, self.plugin_type)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -1635,11 +1599,6 @@ impl ::protobuf::Message for CreateViewParams { |m: &CreateViewParams| { &m.data_type }, |m: &mut CreateViewParams| { &mut m.data_type }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "ext_data", - |m: &CreateViewParams| { &m.ext_data }, - |m: &mut CreateViewParams| { &mut m.ext_data }, - )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "view_id", |m: &CreateViewParams| { &m.view_id }, @@ -1676,7 +1635,6 @@ impl ::protobuf::Clear for CreateViewParams { self.desc.clear(); self.thumbnail.clear(); self.data_type = ViewDataType::TextBlock; - self.ext_data.clear(); self.view_id.clear(); self.data.clear(); self.plugin_type = 0; @@ -2880,32 +2838,32 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x18\t\x20\x01(\x03R\ncreateTime\x12\x19\n\x08ext_data\x18\n\x20\x01(\tR\ \x07extData\x12\x1c\n\tthumbnail\x18\x0b\x20\x01(\tR\tthumbnail\x12\x1f\ \n\x0bplugin_type\x18\x0c\x20\x01(\x05R\npluginType\"+\n\x0cRepeatedView\ - \x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.ViewR\x05items\"\xf9\x01\n\ + \x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.ViewR\x05items\"\xf2\x01\n\ \x11CreateViewPayload\x12\x20\n\x0cbelong_to_id\x18\x01\x20\x01(\tR\nbel\ ongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ \x18\x03\x20\x01(\tR\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\0R\ \tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTypeR\x08d\ - ataType\x12\x19\n\x08ext_data\x18\x06\x20\x01(\tR\x07extData\x12\x1f\n\ - \x0bplugin_type\x18\x07\x20\x01(\x05R\npluginTypeB\x12\n\x10one_of_thumb\ - nail\"\x8f\x02\n\x10CreateViewParams\x12\x20\n\x0cbelong_to_id\x18\x01\ - \x20\x01(\tR\nbelongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\ - \x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1c\n\tthumbnail\x18\ - \x04\x20\x01(\tR\tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.Vi\ - ewDataTypeR\x08dataType\x12\x19\n\x08ext_data\x18\x06\x20\x01(\tR\x07ext\ - Data\x12\x17\n\x07view_id\x18\x07\x20\x01(\tR\x06viewId\x12\x12\n\x04dat\ - a\x18\x08\x20\x01(\tR\x04data\x12\x1f\n\x0bplugin_type\x18\t\x20\x01(\ - \x05R\npluginType\"\x1e\n\x06ViewId\x12\x14\n\x05value\x18\x01\x20\x01(\ - \tR\x05value\"&\n\x0eRepeatedViewId\x12\x14\n\x05items\x18\x01\x20\x03(\ - \tR\x05items\"\xaa\x01\n\x11UpdateViewPayload\x12\x17\n\x07view_id\x18\ - \x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04n\ - ame\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12\x1e\n\tthumbn\ - ail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of_nameB\r\n\x0bone_\ - of_descB\x12\n\x10one_of_thumbnail\"\xa9\x01\n\x10UpdateViewParams\x12\ - \x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\ - \x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\ - \x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\ - \x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail*'\n\x0cVi\ - ewDataType\x12\r\n\tTextBlock\x10\0\x12\x08\n\x04Grid\x10\x01b\x06proto3\ + ataType\x12\x1f\n\x0bplugin_type\x18\x06\x20\x01(\x05R\npluginType\x12\ + \x12\n\x04data\x18\x07\x20\x01(\tR\x04dataB\x12\n\x10one_of_thumbnail\"\ + \xf4\x01\n\x10CreateViewParams\x12\x20\n\x0cbelong_to_id\x18\x01\x20\x01\ + (\tR\nbelongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\ + \x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1c\n\tthumbnail\x18\x04\x20\ + \x01(\tR\tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTy\ + peR\x08dataType\x12\x17\n\x07view_id\x18\x06\x20\x01(\tR\x06viewId\x12\ + \x12\n\x04data\x18\x07\x20\x01(\tR\x04data\x12\x1f\n\x0bplugin_type\x18\ + \x08\x20\x01(\x05R\npluginType\"\x1e\n\x06ViewId\x12\x14\n\x05value\x18\ + \x01\x20\x01(\tR\x05value\"&\n\x0eRepeatedViewId\x12\x14\n\x05items\x18\ + \x01\x20\x03(\tR\x05items\"\xaa\x01\n\x11UpdateViewPayload\x12\x17\n\x07\ + view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\x01(\ + \tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12\ + \x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of_nam\ + eB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail\"\xa9\x01\n\x10UpdateVi\ + ewParams\x12\x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\ + \x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\ + \x01(\tH\x01R\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthu\ + mbnailB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnai\ + l*'\n\x0cViewDataType\x12\r\n\tTextBlock\x10\0\x12\x08\n\x04Grid\x10\x01\ + b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto index 9d51c50263..b66f778a71 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto +++ b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto @@ -23,8 +23,8 @@ message CreateViewPayload { string desc = 3; oneof one_of_thumbnail { string thumbnail = 4; }; ViewDataType data_type = 5; - string ext_data = 6; - int32 plugin_type = 7; + int32 plugin_type = 6; + string data = 7; } message CreateViewParams { string belong_to_id = 1; @@ -32,10 +32,9 @@ message CreateViewParams { string desc = 3; string thumbnail = 4; ViewDataType data_type = 5; - string ext_data = 6; - string view_id = 7; - string data = 8; - int32 plugin_type = 9; + string view_id = 6; + string data = 7; + int32 plugin_type = 8; } message ViewId { string value = 1; 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 ef84bfe104..e708dc8ee7 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,6 +1,7 @@ -use crate::entities::{Field, RowMeta}; +use crate::entities::{FieldMeta, FieldType, RowMeta}; use flowy_derive::ProtoBuf; use std::collections::HashMap; +use std::sync::Arc; #[derive(Debug, Clone, Default, ProtoBuf)] pub struct Grid { @@ -14,20 +15,82 @@ pub struct Grid { pub row_orders: Vec, } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct Field { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub name: String, + + #[pb(index = 3)] + pub desc: String, + + #[pb(index = 4)] + pub field_type: FieldType, + + #[pb(index = 5)] + pub frozen: bool, + + #[pb(index = 6)] + pub visibility: bool, + + #[pb(index = 7)] + pub width: i32, +} + #[derive(Debug, Clone, Default, ProtoBuf)] pub struct FieldOrder { #[pb(index = 1)] pub field_id: String, } -impl std::convert::From<&Field> for FieldOrder { - fn from(field: &Field) -> Self { +impl std::convert::From<&FieldMeta> for FieldOrder { + fn from(field_meta: &FieldMeta) -> Self { Self { - field_id: field.id.clone(), + field_id: field_meta.id.clone(), } } } +impl std::convert::From for Field { + fn from(field_meta: FieldMeta) -> Self { + Self { + id: field_meta.id, + name: field_meta.name, + desc: field_meta.desc, + field_type: field_meta.field_type, + frozen: field_meta.frozen, + visibility: field_meta.visibility, + width: field_meta.width, + } + } +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct RepeatedField { + #[pb(index = 1)] + pub items: Vec, +} +impl std::ops::Deref for RepeatedField { + type Target = Vec; + fn deref(&self) -> &Self::Target { + &self.items + } +} + +impl std::ops::DerefMut for RepeatedField { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.items + } +} + +impl std::convert::From> for RepeatedField { + fn from(items: Vec) -> Self { + Self { items } + } +} + #[derive(Debug, Clone, Default, ProtoBuf)] pub struct RepeatedFieldOrder { #[pb(index = 1)] @@ -59,6 +122,15 @@ impl std::convert::From<&RowMeta> for RowOrder { } } +impl std::convert::From<&Arc> for RowOrder { + fn from(row: &Arc) -> Self { + Self { + row_id: row.id.clone(), + block_id: row.block_id.clone(), + } + } +} + #[derive(Debug, Clone, Default, ProtoBuf)] pub struct RepeatedRowOrder { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 05de0efa05..c7cd8338c8 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -12,7 +12,7 @@ pub struct GridMeta { pub grid_id: String, #[pb(index = 2)] - pub fields: Vec, + pub fields: Vec, #[pb(index = 3)] pub blocks: Vec, @@ -30,6 +30,12 @@ pub struct GridBlock { pub row_count: i32, } +impl GridBlock { + pub fn len(&self) -> i32 { + self.start_row_index + self.row_count + } +} + impl GridBlock { pub fn new() -> Self { GridBlock { @@ -65,7 +71,7 @@ pub struct GridBlockMeta { } #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf, PartialEq, Eq)] -pub struct Field { +pub struct FieldMeta { #[pb(index = 1)] pub id: String, @@ -91,7 +97,7 @@ pub struct Field { pub type_options: String, } -impl Field { +impl FieldMeta { pub fn new(name: &str, desc: &str, field_type: FieldType) -> Self { Self { id: uuid::Uuid::new_v4().to_string(), @@ -133,30 +139,6 @@ pub struct FieldChangeset { pub type_options: Option, } -#[derive(Debug, Default, ProtoBuf)] -pub struct RepeatedField { - #[pb(index = 1)] - pub items: Vec, -} -impl std::ops::Deref for RepeatedField { - type Target = Vec; - fn deref(&self) -> &Self::Target { - &self.items - } -} - -impl std::ops::DerefMut for RepeatedField { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.items - } -} - -impl std::convert::From> for RepeatedField { - fn from(items: Vec) -> Self { - Self { items } - } -} - #[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)] pub enum FieldType { RichText = 0, @@ -180,8 +162,8 @@ impl AsRef for FieldType { } impl From<&FieldType> for FieldType { - fn from(field: &FieldType) -> Self { - field.clone() + fn from(field_type: &FieldType) -> Self { + field_type.clone() } } 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 e7a7561068..4070675fd6 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 @@ -280,6 +280,385 @@ impl ::protobuf::reflect::ProtobufValue for Grid { } } +#[derive(PartialEq,Clone,Default)] +pub struct Field { + // message fields + pub id: ::std::string::String, + pub name: ::std::string::String, + pub desc: ::std::string::String, + pub field_type: super::meta::FieldType, + pub frozen: bool, + pub visibility: bool, + pub width: i32, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Field { + fn default() -> &'a Field { + ::default_instance() + } +} + +impl Field { + pub fn new() -> Field { + ::std::default::Default::default() + } + + // string id = 1; + + + pub fn get_id(&self) -> &str { + &self.id + } + pub fn clear_id(&mut self) { + self.id.clear(); + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: ::std::string::String) { + self.id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id + } + + // Take field + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) + } + + // string name = 2; + + + pub fn get_name(&self) -> &str { + &self.name + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + &mut self.name + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.name, ::std::string::String::new()) + } + + // string desc = 3; + + + pub fn get_desc(&self) -> &str { + &self.desc + } + pub fn clear_desc(&mut self) { + self.desc.clear(); + } + + // Param is passed by value, moved + pub fn set_desc(&mut self, v: ::std::string::String) { + self.desc = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_desc(&mut self) -> &mut ::std::string::String { + &mut self.desc + } + + // Take field + pub fn take_desc(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.desc, ::std::string::String::new()) + } + + // .FieldType field_type = 4; + + + pub fn get_field_type(&self) -> super::meta::FieldType { + self.field_type + } + pub fn clear_field_type(&mut self) { + self.field_type = super::meta::FieldType::RichText; + } + + // Param is passed by value, moved + pub fn set_field_type(&mut self, v: super::meta::FieldType) { + self.field_type = v; + } + + // bool frozen = 5; + + + pub fn get_frozen(&self) -> bool { + self.frozen + } + pub fn clear_frozen(&mut self) { + self.frozen = false; + } + + // Param is passed by value, moved + pub fn set_frozen(&mut self, v: bool) { + self.frozen = v; + } + + // bool visibility = 6; + + + pub fn get_visibility(&self) -> bool { + self.visibility + } + pub fn clear_visibility(&mut self) { + self.visibility = false; + } + + // Param is passed by value, moved + pub fn set_visibility(&mut self, v: bool) { + self.visibility = v; + } + + // int32 width = 7; + + + pub fn get_width(&self) -> i32 { + self.width + } + pub fn clear_width(&mut self) { + self.width = 0; + } + + // Param is passed by value, moved + pub fn set_width(&mut self, v: i32) { + self.width = v; + } +} + +impl ::protobuf::Message for Field { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.desc)?; + }, + 4 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.field_type, 4, &mut self.unknown_fields)? + }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.frozen = tmp; + }, + 6 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.visibility = tmp; + }, + 7 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.width = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + if !self.name.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.name); + } + if !self.desc.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.desc); + } + if self.field_type != super::meta::FieldType::RichText { + my_size += ::protobuf::rt::enum_size(4, self.field_type); + } + if self.frozen != false { + my_size += 2; + } + if self.visibility != false { + my_size += 2; + } + if self.width != 0 { + my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + if !self.name.is_empty() { + os.write_string(2, &self.name)?; + } + if !self.desc.is_empty() { + os.write_string(3, &self.desc)?; + } + if self.field_type != super::meta::FieldType::RichText { + os.write_enum(4, ::protobuf::ProtobufEnum::value(&self.field_type))?; + } + if self.frozen != false { + os.write_bool(5, self.frozen)?; + } + if self.visibility != false { + os.write_bool(6, self.visibility)?; + } + if self.width != 0 { + os.write_int32(7, self.width)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Field { + Field::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &Field| { &m.id }, + |m: &mut Field| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &Field| { &m.name }, + |m: &mut Field| { &mut m.name }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "desc", + |m: &Field| { &m.desc }, + |m: &mut Field| { &mut m.desc }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "field_type", + |m: &Field| { &m.field_type }, + |m: &mut Field| { &mut m.field_type }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "frozen", + |m: &Field| { &m.frozen }, + |m: &mut Field| { &mut m.frozen }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "visibility", + |m: &Field| { &m.visibility }, + |m: &mut Field| { &mut m.visibility }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "width", + |m: &Field| { &m.width }, + |m: &mut Field| { &mut m.width }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Field", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Field { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Field::new) + } +} + +impl ::protobuf::Clear for Field { + fn clear(&mut self) { + self.id.clear(); + self.name.clear(); + self.desc.clear(); + self.field_type = super::meta::FieldType::RichText; + self.frozen = false; + self.visibility = false; + self.width = 0; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Field { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Field { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct FieldOrder { // message fields @@ -439,6 +818,172 @@ impl ::protobuf::reflect::ProtobufValue for FieldOrder { } } +#[derive(PartialEq,Clone,Default)] +pub struct RepeatedField { + // message fields + pub items: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RepeatedField { + fn default() -> &'a RepeatedField { + ::default_instance() + } +} + +impl RepeatedField { + pub fn new() -> RepeatedField { + ::std::default::Default::default() + } + + // repeated .Field items = 1; + + + pub fn get_items(&self) -> &[Field] { + &self.items + } + pub fn clear_items(&mut self) { + self.items.clear(); + } + + // Param is passed by value, moved + pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { + self.items = v; + } + + // Mutable pointer to the field. + pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.items + } + + // Take field + pub fn take_items(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for RepeatedField { + fn is_initialized(&self) -> bool { + for v in &self.items { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.items { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.items { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RepeatedField { + RepeatedField::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "items", + |m: &RepeatedField| { &m.items }, + |m: &mut RepeatedField| { &mut m.items }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedField", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RepeatedField { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedField::new) + } +} + +impl ::protobuf::Clear for RepeatedField { + fn clear(&mut self) { + self.items.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RepeatedField { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RepeatedField { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct RepeatedFieldOrder { // message fields @@ -2321,29 +2866,35 @@ impl ::protobuf::reflect::ProtobufValue for QueryRowPayload { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ngrid.proto\"p\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ - \x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrderR\x0bfieldOr\ - ders\x12(\n\nrow_orders\x18\x03\x20\x03(\x0b2\t.RowOrderR\trowOrders\"'\ - \n\nFieldOrder\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"7\n\ - \x12RepeatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOr\ - derR\x05items\"<\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\ - \x05rowId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\"3\n\x10R\ - epeatedRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05\ - items\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12@\ - \n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\ - \rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\ - \n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\ - \x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\ - \x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05ite\ - ms\";\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\ - \x18\n\x07content\x18\x02\x20\x01(\tR\x07content\"'\n\x11CreateGridPaylo\ - ad\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\ - \x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"d\n\x11QueryFieldPayload\ - \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orde\ - rs\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\\\n\ - \x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ - \x120\n\nrow_orders\x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrderR\trowOrde\ - rsb\x06proto3\ + \n\ngrid.proto\x1a\nmeta.proto\"p\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\ + \x01(\tR\x02id\x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrd\ + erR\x0bfieldOrders\x12(\n\nrow_orders\x18\x03\x20\x03(\x0b2\t.RowOrderR\ + \trowOrders\"\xb8\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02\ + id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\ + \x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.Fiel\ + dTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06frozen\ + \x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05wi\ + dth\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\x19\n\x08field_i\ + d\x18\x01\x20\x01(\tR\x07fieldId\"-\n\rRepeatedField\x12\x1c\n\x05items\ + \x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFieldOrder\ + \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"<\n\x08\ + RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08b\ + lock_id\x18\x02\x20\x01(\tR\x07blockId\"3\n\x10RepeatedRowOrder\x12\x1f\ + \n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05items\"\xb8\x01\n\x03Ro\ + w\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\ + \x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\ + \x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldId\ + Entry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\ + \x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\ + \x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05items\";\n\x04Cell\x12\ + \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\ + \x18\x02\x20\x01(\tR\x07content\"'\n\x11CreateGridPayload\x12\x12\n\x04n\ + ame\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\ + \x01\x20\x01(\tR\x05value\"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\"\\\n\x0fQueryRowPayload\ + \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x120\n\nrow_orders\ + \x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrderR\trowOrdersb\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/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index c8146c452a..bd01ee6cf6 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -27,7 +27,7 @@ pub struct GridMeta { // message fields pub grid_id: ::std::string::String, - pub fields: ::protobuf::RepeatedField, + pub fields: ::protobuf::RepeatedField, pub blocks: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, @@ -71,10 +71,10 @@ impl GridMeta { ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) } - // repeated .Field fields = 2; + // repeated .FieldMeta fields = 2; - pub fn get_fields(&self) -> &[Field] { + pub fn get_fields(&self) -> &[FieldMeta] { &self.fields } pub fn clear_fields(&mut self) { @@ -82,17 +82,17 @@ impl GridMeta { } // Param is passed by value, moved - pub fn set_fields(&mut self, v: ::protobuf::RepeatedField) { + pub fn set_fields(&mut self, v: ::protobuf::RepeatedField) { self.fields = v; } // Mutable pointer to the field. - pub fn mut_fields(&mut self) -> &mut ::protobuf::RepeatedField { + pub fn mut_fields(&mut self) -> &mut ::protobuf::RepeatedField { &mut self.fields } // Take field - pub fn take_fields(&mut self) -> ::protobuf::RepeatedField { + pub fn take_fields(&mut self) -> ::protobuf::RepeatedField { ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new()) } @@ -235,7 +235,7 @@ impl ::protobuf::Message for GridMeta { |m: &GridMeta| { &m.grid_id }, |m: &mut GridMeta| { &mut m.grid_id }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "fields", |m: &GridMeta| { &m.fields }, |m: &mut GridMeta| { &mut m.fields }, @@ -718,7 +718,7 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockMeta { } #[derive(PartialEq,Clone,Default)] -pub struct Field { +pub struct FieldMeta { // message fields pub id: ::std::string::String, pub name: ::std::string::String, @@ -733,14 +733,14 @@ pub struct Field { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a Field { - fn default() -> &'a Field { - ::default_instance() +impl<'a> ::std::default::Default for &'a FieldMeta { + fn default() -> &'a FieldMeta { + ::default_instance() } } -impl Field { - pub fn new() -> Field { +impl FieldMeta { + pub fn new() -> FieldMeta { ::std::default::Default::default() } @@ -909,7 +909,7 @@ impl Field { } } -impl ::protobuf::Message for Field { +impl ::protobuf::Message for FieldMeta { fn is_initialized(&self) -> bool { true } @@ -1050,8 +1050,8 @@ impl ::protobuf::Message for Field { Self::descriptor_static() } - fn new() -> Field { - Field::new() + fn new() -> FieldMeta { + FieldMeta::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -1060,59 +1060,59 @@ impl ::protobuf::Message for Field { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "id", - |m: &Field| { &m.id }, - |m: &mut Field| { &mut m.id }, + |m: &FieldMeta| { &m.id }, + |m: &mut FieldMeta| { &mut m.id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "name", - |m: &Field| { &m.name }, - |m: &mut Field| { &mut m.name }, + |m: &FieldMeta| { &m.name }, + |m: &mut FieldMeta| { &mut m.name }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "desc", - |m: &Field| { &m.desc }, - |m: &mut Field| { &mut m.desc }, + |m: &FieldMeta| { &m.desc }, + |m: &mut FieldMeta| { &mut m.desc }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( "field_type", - |m: &Field| { &m.field_type }, - |m: &mut Field| { &mut m.field_type }, + |m: &FieldMeta| { &m.field_type }, + |m: &mut FieldMeta| { &mut m.field_type }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( "frozen", - |m: &Field| { &m.frozen }, - |m: &mut Field| { &mut m.frozen }, + |m: &FieldMeta| { &m.frozen }, + |m: &mut FieldMeta| { &mut m.frozen }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( "visibility", - |m: &Field| { &m.visibility }, - |m: &mut Field| { &mut m.visibility }, + |m: &FieldMeta| { &m.visibility }, + |m: &mut FieldMeta| { &mut m.visibility }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( "width", - |m: &Field| { &m.width }, - |m: &mut Field| { &mut m.width }, + |m: &FieldMeta| { &m.width }, + |m: &mut FieldMeta| { &mut m.width }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "type_options", - |m: &Field| { &m.type_options }, - |m: &mut Field| { &mut m.type_options }, + |m: &FieldMeta| { &m.type_options }, + |m: &mut FieldMeta| { &mut m.type_options }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "Field", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "FieldMeta", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static Field { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(Field::new) + fn default_instance() -> &'static FieldMeta { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(FieldMeta::new) } } -impl ::protobuf::Clear for Field { +impl ::protobuf::Clear for FieldMeta { fn clear(&mut self) { self.id.clear(); self.name.clear(); @@ -1126,13 +1126,13 @@ impl ::protobuf::Clear for Field { } } -impl ::std::fmt::Debug for Field { +impl ::std::fmt::Debug for FieldMeta { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for Field { +impl ::protobuf::reflect::ProtobufValue for FieldMeta { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -1769,172 +1769,6 @@ impl ::protobuf::reflect::ProtobufValue for FieldChangeset { } } -#[derive(PartialEq,Clone,Default)] -pub struct RepeatedField { - // message fields - pub items: ::protobuf::RepeatedField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RepeatedField { - fn default() -> &'a RepeatedField { - ::default_instance() - } -} - -impl RepeatedField { - pub fn new() -> RepeatedField { - ::std::default::Default::default() - } - - // repeated .Field items = 1; - - - pub fn get_items(&self) -> &[Field] { - &self.items - } - pub fn clear_items(&mut self) { - self.items.clear(); - } - - // Param is passed by value, moved - pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { - self.items = v; - } - - // Mutable pointer to the field. - pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.items - } - - // Take field - pub fn take_items(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for RepeatedField { - fn is_initialized(&self) -> bool { - for v in &self.items { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.items { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.items { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RepeatedField { - RepeatedField::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "items", - |m: &RepeatedField| { &m.items }, - |m: &mut RepeatedField| { &mut m.items }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RepeatedField", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RepeatedField { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RepeatedField::new) - } -} - -impl ::protobuf::Clear for RepeatedField { - fn clear(&mut self) { - self.items.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RepeatedField { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RepeatedField { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct AnyData { // message fields @@ -3302,19 +3136,19 @@ impl ::protobuf::reflect::ProtobufValue for FieldType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\nmeta.proto\"g\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ - \x06gridId\x12\x1e\n\x06fields\x18\x02\x20\x03(\x0b2\x06.FieldR\x06field\ + \n\nmeta.proto\"k\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \x06gridId\x12\"\n\x06fields\x18\x02\x20\x03(\x0b2\n.FieldMetaR\x06field\ s\x12\"\n\x06blocks\x18\x03\x20\x03(\x0b2\n.GridBlockR\x06blocks\"`\n\tG\ ridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12&\n\x0fstart_row_i\ ndex\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\ \x20\x01(\x05R\x08rowCount\"H\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\ \x01\x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.\ - RowMetaR\x04rows\"\xdb\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\t\ - R\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ - \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\ - FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ - n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ - idth\x18\x07\x20\x01(\x05R\x05width\x12!\n\x0ctype_options\x18\x08\x20\ + RowMetaR\x04rows\"\xdf\x01\n\tFieldMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ + \tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04des\ + c\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n\ + .FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froz\ + en\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05\ + width\x18\x07\x20\x01(\x05R\x05width\x12!\n\x0ctype_options\x18\x08\x20\ \x01(\tR\x0btypeOptions\"\xfd\x02\n\x0eFieldChangeset\x12\x19\n\x08field\ _id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04name\x18\x02\x20\x01(\tH\ \0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12+\n\nf\ @@ -3324,31 +3158,30 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01(\x05H\x05R\x05width\x12#\n\x0ctype_options\x18\x08\x20\x01(\tH\x06R\ \x0btypeOptionsB\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\x0c\ - one_of_widthB\x15\n\x13one_of_type_options\"-\n\rRepeatedField\x12\x1c\n\ - \x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"8\n\x07AnyData\x12\ - \x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\ - \x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\ - \x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07bloc\ - kId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByF\ - ieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\ - \x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\ - \n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\ - \x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\ - \xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\ - \x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\ - \n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_\ - field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rce\ - llByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\ - \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\ - value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"9\n\ - \x08CellMeta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\ - \x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"j\n\x11CellMetaChangeset\x12\ - \x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\ - \x02\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x03\x20\x01(\tH\0R\x04\ - dataB\r\n\x0bone_of_data*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\ - \n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingle\ - Select\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\ - \x10\x05b\x06proto3\ + one_of_widthB\x15\n\x13one_of_type_options\"8\n\x07AnyData\x12\x17\n\x07\ + type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\x20\x01\ + (\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ + \tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12D\n\ + \x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByFieldIdEntr\ + yR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06height\ + \x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\n\x12CellB\ + yFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05v\ + alue\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\xa7\x02\n\ + \x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ + \x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\n\nvisib\ + ility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_field_id\ + \x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rcellByFiel\ + dId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\ + \x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\ + \x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"9\n\x08Cell\ + Meta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x12\n\x04d\ + ata\x18\x02\x20\x01(\tR\x04data\"j\n\x11CellMetaChangeset\x12\x15\n\x06r\ + ow_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x02\x20\x01\ + (\tR\x07fieldId\x12\x14\n\x04data\x18\x03\x20\x01(\tH\0R\x04dataB\r\n\ + \x0bone_of_data*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Nu\ + mber\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\ + \x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06\ + proto3\ "; 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 4e395edc92..66dba465f6 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 @@ -1,13 +1,26 @@ syntax = "proto3"; +import "meta.proto"; message Grid { string id = 1; repeated FieldOrder field_orders = 2; repeated RowOrder row_orders = 3; } +message Field { + string id = 1; + string name = 2; + string desc = 3; + FieldType field_type = 4; + bool frozen = 5; + bool visibility = 6; + int32 width = 7; +} message FieldOrder { string field_id = 1; } +message RepeatedField { + repeated Field items = 1; +} message RepeatedFieldOrder { repeated FieldOrder items = 1; } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 77185fff5d..32fc3896ac 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -2,7 +2,7 @@ syntax = "proto3"; message GridMeta { string grid_id = 1; - repeated Field fields = 2; + repeated FieldMeta fields = 2; repeated GridBlock blocks = 3; } message GridBlock { @@ -14,7 +14,7 @@ message GridBlockMeta { string block_id = 1; repeated RowMeta rows = 2; } -message Field { +message FieldMeta { string id = 1; string name = 2; string desc = 3; @@ -34,9 +34,6 @@ message FieldChangeset { oneof one_of_width { int32 width = 7; }; oneof one_of_type_options { string type_options = 8; }; } -message RepeatedField { - repeated Field items = 1; -} message AnyData { string type_id = 1; bytes value = 2; diff --git a/shared-lib/flowy-grid-data-model/tests/serde_test.rs b/shared-lib/flowy-grid-data-model/tests/serde_test.rs index 49780e2a52..0847950b98 100644 --- a/shared-lib/flowy-grid-data-model/tests/serde_test.rs +++ b/shared-lib/flowy-grid-data-model/tests/serde_test.rs @@ -31,8 +31,8 @@ fn grid_default_serde_test() { assert_eq!(json, r#"{"id":"1","fields":[],"blocks":[]}"#) } -fn create_field(field_id: &str) -> Field { - let mut field = Field::new("Text Field", "", FieldType::RichText); +fn create_field(field_id: &str) -> FieldMeta { + let mut field = FieldMeta::new("Text Field", "", FieldType::RichText); field.id = field_id.to_string(); field } From 47081f3095fec609baa10c3b04d48c48846ead6c Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 15 Mar 2022 19:00:28 +0800 Subject: [PATCH 21/28] chore: update grid test --- .../flowy-folder-data-model/view.pb.dart | 16 +- .../flowy-folder-data-model/view.pbjson.dart | 8 +- .../flowy-grid-data-model/meta.pb.dart | 73 +++++ .../flowy-grid-data-model/meta.pbjson.dart | 12 + frontend/rust-lib/Cargo.lock | 1 + frontend/rust-lib/flowy-block/src/queue.rs | 4 +- frontend/rust-lib/flowy-folder/src/manager.rs | 6 +- .../src/services/folder_editor.rs | 4 +- .../src/services/persistence/mod.rs | 2 +- .../src/services/view/controller.rs | 13 +- frontend/rust-lib/flowy-grid/src/manager.rs | 35 ++- .../src/services/block_meta_editor.rs | 4 +- .../flowy-grid/src/services/grid_editor.rs | 12 +- frontend/rust-lib/flowy-grid/src/util.rs | 9 +- .../flowy-grid/tests/grid/grid_test.rs | 49 ++- .../rust-lib/flowy-grid/tests/grid/script.rs | 110 ++++++- frontend/rust-lib/flowy-sdk/Cargo.toml | 1 + .../flowy-sdk/src/deps_resolve/folder_deps.rs | 63 ++-- .../flowy-sync/src/conflict_resolve.rs | 4 +- frontend/rust-lib/flowy-test/src/helper.rs | 8 +- .../src/client_document/document_pad.rs | 5 +- .../src/client_folder/folder_pad.rs | 2 +- .../src/client_grid/block_pad.rs | 4 +- .../src/client_grid/grid_builder.rs | 86 ++---- .../src/client_grid/grid_pad.rs | 17 +- .../src/entities/view.rs | 4 +- .../src/protobuf/model/view.rs | 76 ++--- .../src/protobuf/proto/view.proto | 4 +- .../src/entities/meta.rs | 35 ++- .../src/protobuf/model/meta.rs | 291 +++++++++++++++++- .../src/protobuf/proto/meta.proto | 5 + shared-lib/lib-ot/src/core/delta/delta.rs | 2 +- 32 files changed, 746 insertions(+), 219 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart index 350b5eac85..98882f444d 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart @@ -276,7 +276,7 @@ class CreateViewPayload extends $pb.GeneratedMessage { ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) ..a<$core.int>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) - ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') + ..a<$core.List<$core.int>>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY) ..hasRequiredFields = false ; @@ -288,7 +288,7 @@ class CreateViewPayload extends $pb.GeneratedMessage { $core.String? thumbnail, ViewDataType? dataType, $core.int? pluginType, - $core.String? data, + $core.List<$core.int>? data, }) { final _result = create(); if (belongToId != null) { @@ -393,9 +393,9 @@ class CreateViewPayload extends $pb.GeneratedMessage { void clearPluginType() => clearField(6); @$pb.TagNumber(7) - $core.String get data => $_getSZ(6); + $core.List<$core.int> get data => $_getN(6); @$pb.TagNumber(7) - set data($core.String v) { $_setString(6, v); } + set data($core.List<$core.int> v) { $_setBytes(6, v); } @$pb.TagNumber(7) $core.bool hasData() => $_has(6); @$pb.TagNumber(7) @@ -410,7 +410,7 @@ class CreateViewParams extends $pb.GeneratedMessage { ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail') ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewId') - ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') + ..a<$core.List<$core.int>>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY) ..a<$core.int>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3) ..hasRequiredFields = false ; @@ -423,7 +423,7 @@ class CreateViewParams extends $pb.GeneratedMessage { $core.String? thumbnail, ViewDataType? dataType, $core.String? viewId, - $core.String? data, + $core.List<$core.int>? data, $core.int? pluginType, }) { final _result = create(); @@ -529,9 +529,9 @@ class CreateViewParams extends $pb.GeneratedMessage { void clearViewId() => clearField(6); @$pb.TagNumber(7) - $core.String get data => $_getSZ(6); + $core.List<$core.int> get data => $_getN(6); @$pb.TagNumber(7) - set data($core.String v) { $_setString(6, v); } + set data($core.List<$core.int> v) { $_setBytes(6, v); } @$pb.TagNumber(7) $core.bool hasData() => $_has(6); @$pb.TagNumber(7) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart index 358cb41100..0f1949754f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart @@ -60,7 +60,7 @@ const CreateViewPayload$json = const { const {'1': 'thumbnail', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'thumbnail'}, const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'}, const {'1': 'plugin_type', '3': 6, '4': 1, '5': 5, '10': 'pluginType'}, - const {'1': 'data', '3': 7, '4': 1, '5': 9, '10': 'data'}, + const {'1': 'data', '3': 7, '4': 1, '5': 12, '10': 'data'}, ], '8': const [ const {'1': 'one_of_thumbnail'}, @@ -68,7 +68,7 @@ const CreateViewPayload$json = const { }; /// Descriptor for `CreateViewPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createViewPayloadDescriptor = $convert.base64Decode('ChFDcmVhdGVWaWV3UGF5bG9hZBIgCgxiZWxvbmdfdG9faWQYASABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEh4KCXRodW1ibmFpbBgEIAEoCUgAUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIfCgtwbHVnaW5fdHlwZRgGIAEoBVIKcGx1Z2luVHlwZRISCgRkYXRhGAcgASgJUgRkYXRhQhIKEG9uZV9vZl90aHVtYm5haWw='); +final $typed_data.Uint8List createViewPayloadDescriptor = $convert.base64Decode('ChFDcmVhdGVWaWV3UGF5bG9hZBIgCgxiZWxvbmdfdG9faWQYASABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEh4KCXRodW1ibmFpbBgEIAEoCUgAUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIfCgtwbHVnaW5fdHlwZRgGIAEoBVIKcGx1Z2luVHlwZRISCgRkYXRhGAcgASgMUgRkYXRhQhIKEG9uZV9vZl90aHVtYm5haWw='); @$core.Deprecated('Use createViewParamsDescriptor instead') const CreateViewParams$json = const { '1': 'CreateViewParams', @@ -79,13 +79,13 @@ const CreateViewParams$json = const { const {'1': 'thumbnail', '3': 4, '4': 1, '5': 9, '10': 'thumbnail'}, const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'}, const {'1': 'view_id', '3': 6, '4': 1, '5': 9, '10': 'viewId'}, - const {'1': 'data', '3': 7, '4': 1, '5': 9, '10': 'data'}, + const {'1': 'data', '3': 7, '4': 1, '5': 12, '10': 'data'}, const {'1': 'plugin_type', '3': 8, '4': 1, '5': 5, '10': 'pluginType'}, ], }; /// Descriptor for `CreateViewParams`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createViewParamsDescriptor = $convert.base64Decode('ChBDcmVhdGVWaWV3UGFyYW1zEiAKDGJlbG9uZ190b19pZBgBIAEoCVIKYmVsb25nVG9JZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSHAoJdGh1bWJuYWlsGAQgASgJUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIXCgd2aWV3X2lkGAYgASgJUgZ2aWV3SWQSEgoEZGF0YRgHIAEoCVIEZGF0YRIfCgtwbHVnaW5fdHlwZRgIIAEoBVIKcGx1Z2luVHlwZQ=='); +final $typed_data.Uint8List createViewParamsDescriptor = $convert.base64Decode('ChBDcmVhdGVWaWV3UGFyYW1zEiAKDGJlbG9uZ190b19pZBgBIAEoCVIKYmVsb25nVG9JZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSHAoJdGh1bWJuYWlsGAQgASgJUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIXCgd2aWV3X2lkGAYgASgJUgZ2aWV3SWQSEgoEZGF0YRgHIAEoDFIEZGF0YRIfCgtwbHVnaW5fdHlwZRgIIAEoBVIKcGx1Z2luVHlwZQ=='); @$core.Deprecated('Use viewIdDescriptor instead') const ViewId$json = const { '1': 'ViewId', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 49168b0274..0a0837d2df 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -1003,3 +1003,76 @@ class CellMetaChangeset extends $pb.GeneratedMessage { void clearData() => clearField(3); } +class BuildGridContext extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BuildGridContext', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldMetas', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlock', subBuilder: GridBlock.create) + ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlockMeta', subBuilder: GridBlockMeta.create) + ..hasRequiredFields = false + ; + + BuildGridContext._() : super(); + factory BuildGridContext({ + $core.Iterable? fieldMetas, + GridBlock? gridBlock, + GridBlockMeta? gridBlockMeta, + }) { + final _result = create(); + if (fieldMetas != null) { + _result.fieldMetas.addAll(fieldMetas); + } + if (gridBlock != null) { + _result.gridBlock = gridBlock; + } + if (gridBlockMeta != null) { + _result.gridBlockMeta = gridBlockMeta; + } + return _result; + } + factory BuildGridContext.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory BuildGridContext.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + BuildGridContext clone() => BuildGridContext()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + BuildGridContext copyWith(void Function(BuildGridContext) updates) => super.copyWith((message) => updates(message as BuildGridContext)) as BuildGridContext; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static BuildGridContext create() => BuildGridContext._(); + BuildGridContext createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static BuildGridContext getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static BuildGridContext? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get fieldMetas => $_getList(0); + + @$pb.TagNumber(2) + GridBlock get gridBlock => $_getN(1); + @$pb.TagNumber(2) + set gridBlock(GridBlock v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasGridBlock() => $_has(1); + @$pb.TagNumber(2) + void clearGridBlock() => clearField(2); + @$pb.TagNumber(2) + GridBlock ensureGridBlock() => $_ensure(1); + + @$pb.TagNumber(3) + GridBlockMeta get gridBlockMeta => $_getN(2); + @$pb.TagNumber(3) + set gridBlockMeta(GridBlockMeta v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasGridBlockMeta() => $_has(2); + @$pb.TagNumber(3) + void clearGridBlockMeta() => clearField(3); + @$pb.TagNumber(3) + GridBlockMeta ensureGridBlockMeta() => $_ensure(2); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 3921f443c4..4dceb2116b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -191,3 +191,15 @@ const CellMetaChangeset$json = const { /// Descriptor for `CellMetaChangeset`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List cellMetaChangesetDescriptor = $convert.base64Decode('ChFDZWxsTWV0YUNoYW5nZXNldBIVCgZyb3dfaWQYASABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAIgASgJUgdmaWVsZElkEhQKBGRhdGEYAyABKAlIAFIEZGF0YUINCgtvbmVfb2ZfZGF0YQ=='); +@$core.Deprecated('Use buildGridContextDescriptor instead') +const BuildGridContext$json = const { + '1': 'BuildGridContext', + '2': const [ + const {'1': 'field_metas', '3': 1, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fieldMetas'}, + const {'1': 'grid_block', '3': 2, '4': 1, '5': 11, '6': '.GridBlock', '10': 'gridBlock'}, + const {'1': 'grid_block_meta', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'gridBlockMeta'}, + ], +}; + +/// Descriptor for `BuildGridContext`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEikKCmdyaWRfYmxvY2sYAiABKAsyCi5HcmlkQmxvY2tSCWdyaWRCbG9jaxI2Cg9ncmlkX2Jsb2NrX21ldGEYAyABKAsyDi5HcmlkQmxvY2tNZXRhUg1ncmlkQmxvY2tNZXRh'); diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index a4c40e1735..30aa28a798 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1147,6 +1147,7 @@ dependencies = [ "flowy-database", "flowy-folder", "flowy-grid", + "flowy-grid-data-model", "flowy-net", "flowy-sync", "flowy-user", diff --git a/frontend/rust-lib/flowy-block/src/queue.rs b/frontend/rust-lib/flowy-block/src/queue.rs index 94955f38d8..f7932e0850 100644 --- a/frontend/rust-lib/flowy-block/src/queue.rs +++ b/frontend/rust-lib/flowy-block/src/queue.rs @@ -175,7 +175,7 @@ impl EditBlockQueue { } async fn save_local_delta(&self, delta: RichTextDelta, md5: String) -> Result { - let delta_data = delta.to_bytes(); + let delta_data = delta.to_delta_bytes(); let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); let user_id = self.user.user_id()?; let revision = Revision::new( @@ -198,7 +198,7 @@ pub(crate) struct TextBlockRevisionCompactor(); impl RevisionCompactor for TextBlockRevisionCompactor { fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { let delta = make_delta_from_revisions::(revisions)?; - Ok(delta.to_bytes()) + Ok(delta.to_delta_bytes()) } } diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index ffa6fc26cb..8fe34a2065 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -245,9 +245,11 @@ pub trait ViewDataProcessor { fn close_container(&self, view_id: &str) -> FutureResult<(), FlowyError>; - fn delta_str(&self, view_id: &str) -> FutureResult; + fn delta_bytes(&self, view_id: &str) -> FutureResult; - fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult; + fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult; + + fn process_create_view_data(&self, user_id: &str, view_id: &str, data: Vec) -> FutureResult; fn data_type(&self) -> ViewDataType; } 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 7aaa1de7cd..48c83cc612 100644 --- a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs +++ b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs @@ -71,7 +71,7 @@ impl ClientFolderEditor { pub(crate) fn apply_change(&self, change: FolderChange) -> FlowyResult<()> { let FolderChange { delta, md5 } = change; let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); - let delta_data = delta.to_bytes(); + let delta_data = delta.to_delta_bytes(); let revision = Revision::new( &self.rev_manager.object_id, base_rev_id, @@ -128,6 +128,6 @@ struct FolderRevisionCompactor(); impl RevisionCompactor for FolderRevisionCompactor { fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { let delta = make_delta_from_revisions::(revisions)?; - Ok(delta.to_bytes()) + Ok(delta.to_delta_bytes()) } } 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 b05490b70a..16417934e0 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs @@ -115,7 +115,7 @@ impl FolderPersistence { pub async fn save_folder(&self, user_id: &str, folder_id: &FolderId, folder: FolderPad) -> FlowyResult<()> { let pool = self.database.db_pool()?; - let delta_data = initial_folder_delta(&folder)?.to_bytes(); + let delta_data = initial_folder_delta(&folder)?.to_delta_bytes(); let md5 = folder.md5(); let revision = Revision::new(folder_id.as_ref(), 0, 0, delta_data, user_id, md5); let record = RevisionRecord { 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 2d943df032..c9851d6652 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -55,13 +55,14 @@ impl ViewController { #[tracing::instrument(level = "trace", skip(self, params), fields(name = %params.name), err)] pub(crate) async fn create_view_from_params(&self, mut params: CreateViewParams) -> Result { let processor = self.get_data_processor(¶ms.data_type)?; - + let user_id = self.user.user_id()?; if params.data.is_empty() { - let user_id = self.user.user_id()?; let view_data = processor.create_default_view(&user_id, ¶ms.view_id).await?; - params.data = view_data; + params.data = view_data.to_vec(); } else { - let delta_data = Bytes::from(params.data.clone()); + let delta_data = processor + .process_create_view_data(&user_id, ¶ms.view_id, params.data.clone()) + .await?; let _ = self .create_view(¶ms.view_id, params.data_type.clone(), delta_data) .await?; @@ -162,14 +163,14 @@ impl ViewController { .await?; let processor = self.get_data_processor(&view.data_type)?; - let delta_str = processor.delta_str(view_id).await?; + let delta_bytes = processor.delta_bytes(view_id).await?; let duplicate_params = CreateViewParams { belong_to_id: view.belong_to_id.clone(), name: format!("{} (copy)", &view.name), desc: view.desc, thumbnail: view.thumbnail, data_type: view.data_type, - data: delta_str, + data: delta_bytes.to_vec(), view_id: uuid(), plugin_type: view.plugin_type, }; diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index fc79fcf5c0..28a246bd75 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -1,8 +1,11 @@ use crate::services::grid_editor::ClientGridEditor; use crate::services::kv_persistence::GridKVPersistence; +use bytes::Bytes; use dashmap::DashMap; -use flowy_collaboration::entities::revision::RepeatedRevision; +use flowy_collaboration::client_grid::{make_block_meta_delta, make_grid_delta}; +use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; use flowy_error::{FlowyError, FlowyResult}; +use flowy_grid_data_model::entities::{BuildGridContext, GridMeta}; use flowy_sync::disk::{SQLiteGridBlockMetaRevisionPersistence, SQLiteGridRevisionPersistence}; use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; use lib_sqlite::ConnectionPool; @@ -172,3 +175,33 @@ impl GridEditorMap { self.inner.remove(grid_id); } } + +pub async fn make_grid_view_data( + user_id: &str, + view_id: &str, + grid_manager: Arc, + build_context: BuildGridContext, +) -> FlowyResult { + let block_id = build_context.grid_block.id.clone(); + let grid_meta = GridMeta { + grid_id: view_id.to_string(), + fields: build_context.field_metas, + blocks: vec![build_context.grid_block], + }; + + let grid_meta_delta = make_grid_delta(&grid_meta); + let grid_delta_data = grid_meta_delta.to_delta_bytes(); + let repeated_revision: RepeatedRevision = + Revision::initial_revision(user_id, view_id, grid_delta_data.clone()).into(); + let _ = grid_manager.create_grid(view_id, repeated_revision).await?; + + let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta); + let block_meta_delta_data = grid_block_meta_delta.to_delta_bytes(); + let repeated_revision: RepeatedRevision = + Revision::initial_revision(&user_id, &block_id, block_meta_delta_data).into(); + let _ = grid_manager + .create_grid_block_meta(&block_id, repeated_revision) + .await?; + + Ok(grid_delta_data) +} 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 c691e0b12c..fb72f8c34d 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 @@ -280,7 +280,7 @@ impl ClientGridBlockMetaEditor { let GridBlockMetaChange { delta, md5 } = change; let user_id = self.user_id.clone(); let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); - let delta_data = delta.to_bytes(); + let delta_data = delta.to_delta_bytes(); let revision = Revision::new( &self.rev_manager.object_id, base_rev_id, @@ -323,6 +323,6 @@ struct GridBlockMetaRevisionCompactor(); impl RevisionCompactor for GridBlockMetaRevisionCompactor { fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { let delta = make_delta_from_revisions::(revisions)?; - Ok(delta.to_bytes()) + Ok(delta.to_delta_bytes()) } } 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 e45dad5394..86c7a8fc0e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -61,6 +61,10 @@ impl ClientGridEditor { Ok(()) } + pub async fn contain_field(&self, field_meta: &FieldMeta) -> bool { + self.grid_meta_pad.read().await.contain_field(&field_meta.id) + } + pub async fn update_field(&self, change: FieldChangeset) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.update_field(change)?)).await?; Ok(()) @@ -177,8 +181,8 @@ impl ClientGridEditor { Ok(grid_blocks) } - pub async fn delta_str(&self) -> String { - self.grid_meta_pad.read().await.delta_str() + pub async fn delta_bytes(&self) -> Bytes { + self.grid_meta_pad.read().await.delta_bytes() } async fn modify(&self, f: F) -> FlowyResult<()> @@ -199,7 +203,7 @@ impl ClientGridEditor { let GridChange { delta, md5 } = change; let user_id = self.user.user_id()?; let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); - let delta_data = delta.to_bytes(); + let delta_data = delta.to_delta_bytes(); let revision = Revision::new( &self.rev_manager.object_id, base_rev_id, @@ -256,6 +260,6 @@ struct GridRevisionCompactor(); impl RevisionCompactor for GridRevisionCompactor { fn bytes_from_revisions(&self, revisions: Vec) -> FlowyResult { let delta = make_delta_from_revisions::(revisions)?; - Ok(delta.to_bytes()) + Ok(delta.to_delta_bytes()) } } diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index 80f942751a..e7417b5ea7 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -1,9 +1,9 @@ use crate::services::cell::*; use crate::services::field::*; -use flowy_collaboration::client_grid::{BuildGridInfo, GridBuilder}; -use flowy_grid_data_model::entities::FieldType; +use flowy_collaboration::client_grid::GridBuilder; +use flowy_grid_data_model::entities::{BuildGridContext, FieldType}; -pub fn make_default_grid(grid_id: &str) -> BuildGridInfo { +pub fn make_default_grid() -> BuildGridContext { let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::default()) .name("Name") .visibility(true) @@ -20,12 +20,11 @@ pub fn make_default_grid(grid_id: &str) -> BuildGridInfo { .field_type(FieldType::SingleSelect) .build(); - GridBuilder::new(grid_id) + GridBuilder::default() .add_field(text_field) .add_field(single_select_field) .add_empty_row() .add_empty_row() .add_empty_row() .build() - .unwrap() } 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 910589eb53..30469d406f 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -4,57 +4,56 @@ use flowy_grid::services::cell::*; use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, CreateRowContextBuilder}; use flowy_grid_data_model::entities::{FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMetaChangeset}; -#[tokio::test] -async fn default_grid_test() { - let scripts = vec![AssertFieldCount(2), AssertGridMetaPad]; - GridEditorTest::new().await.run_scripts(scripts).await; -} - #[tokio::test] async fn grid_create_field() { + let mut test = GridEditorTest::new().await; let text_field = create_text_field(); let single_select_field = create_single_select_field(); + let scripts = vec![ - AssertFieldCount(2), CreateField { field_meta: text_field.clone(), }, AssertFieldEqual { - field_index: 2, + field_index: test.field_count, field_meta: text_field, }, - AssertFieldCount(3), + ]; + test.run_scripts(scripts).await; + + let scripts = vec![ CreateField { field_meta: single_select_field.clone(), }, AssertFieldEqual { - field_index: 3, + field_index: test.field_count, field_meta: single_select_field, }, - AssertFieldCount(4), ]; - GridEditorTest::new().await.run_scripts(scripts).await; + test.run_scripts(scripts).await; } #[tokio::test] async fn grid_create_duplicate_field() { + let mut test = GridEditorTest::new().await; let text_field = create_text_field(); + let field_count = test.field_count; + let expected_field_count = field_count + 1; let scripts = vec![ - AssertFieldCount(2), CreateField { field_meta: text_field.clone(), }, - AssertFieldCount(3), CreateField { field_meta: text_field.clone(), }, - AssertFieldCount(3), + AssertFieldCount(expected_field_count), ]; - GridEditorTest::new().await.run_scripts(scripts).await; + test.run_scripts(scripts).await; } #[tokio::test] async fn grid_update_field_with_empty_change() { + let mut test = GridEditorTest::new().await; let single_select_field = create_single_select_field(); let changeset = FieldChangeset { field_id: single_select_field.id.clone(), @@ -73,21 +72,21 @@ async fn grid_update_field_with_empty_change() { }, UpdateField { changeset }, AssertFieldEqual { - field_index: 2, + field_index: test.field_count, field_meta: single_select_field, }, ]; - GridEditorTest::new().await.run_scripts(scripts).await; + test.run_scripts(scripts).await; } #[tokio::test] async fn grid_update_field() { + let mut test = GridEditorTest::new().await; let single_select_field = create_single_select_field(); let mut cloned_field = single_select_field.clone(); let mut single_select_type_options = SingleSelectDescription::from(&single_select_field); single_select_type_options.options.push(SelectOption::new("Unknown")); - let changeset = FieldChangeset { field_id: single_select_field.id.clone(), name: None, @@ -109,26 +108,26 @@ async fn grid_update_field() { }, UpdateField { changeset }, AssertFieldEqual { - field_index: 2, + field_index: test.field_count, field_meta: cloned_field, }, - AssertGridMetaPad, ]; - GridEditorTest::new().await.run_scripts(scripts).await; + test.run_scripts(scripts).await; } #[tokio::test] async fn grid_delete_field() { + let mut test = GridEditorTest::new().await; + let expected_field_count = test.field_count; let text_field = create_text_field(); let scripts = vec![ CreateField { field_meta: text_field.clone(), }, - AssertFieldCount(3), DeleteField { field_meta: text_field }, - AssertFieldCount(2), + AssertFieldCount(expected_field_count), ]; - GridEditorTest::new().await.run_scripts(scripts).await; + test.run_scripts(scripts).await; } #[tokio::test] diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 777bad2949..c49bf82a03 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,15 +1,22 @@ +use bytes::Bytes; +use flowy_collaboration::client_grid::GridBuilder; +use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; +use flowy_error::FlowyResult; +use flowy_grid::manager::{make_grid_view_data, GridManager}; use flowy_grid::services::cell::*; use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::row::CreateRowContext; use flowy_grid_data_model::entities::{ - CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlock, GridBlockChangeset, RowMeta, RowMetaChangeset, + BuildGridContext, CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlock, GridBlockChangeset, RowMeta, + RowMetaChangeset, }; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::helper::ViewTest; use flowy_test::FlowySDKTest; use std::sync::Arc; use std::time::Duration; +use strum::{EnumCount, IntoEnumIterator}; use tokio::time::sleep; pub enum EditorScript { @@ -71,19 +78,18 @@ pub struct GridEditorTest { pub field_metas: Vec, pub grid_blocks: Vec, pub row_metas: Vec>, + pub field_count: usize, } impl GridEditorTest { pub async fn new() -> Self { - Self::with_data("".to_owned()).await - } - - pub async fn with_data(data: String) -> Self { let sdk = FlowySDKTest::default(); let _ = sdk.init_user().await; - let test = ViewTest::new_grid_view(&sdk, data).await; + let build_context = make_template_1_grid(); + let view_data: Bytes = build_context.try_into().unwrap(); + let test = ViewTest::new_grid_view(&sdk, view_data.to_vec()).await; let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); - let fields = editor.get_field_metas(None).await.unwrap(); + let field_metas = editor.get_field_metas(None).await.unwrap(); let grid_blocks = editor.get_blocks().await.unwrap(); let row_metas = editor.get_row_metas(None).await.unwrap(); @@ -92,9 +98,10 @@ impl GridEditorTest { sdk, grid_id, editor, - field_metas: fields, + field_metas, grid_blocks, row_metas, + field_count: FieldType::COUNT, } } @@ -111,22 +118,30 @@ impl GridEditorTest { let _cache = rev_manager.revision_cache().await; match script { - EditorScript::CreateField { field_meta: field } => { - self.editor.create_field(field).await.unwrap(); + EditorScript::CreateField { field_meta } => { + if !self.editor.contain_field(&field_meta).await { + self.field_count += 1; + } + self.editor.create_field(field_meta).await.unwrap(); self.field_metas = self.editor.get_field_metas(None).await.unwrap(); + assert_eq!(self.field_count, self.field_metas.len()); } EditorScript::UpdateField { changeset: change } => { self.editor.update_field(change).await.unwrap(); self.field_metas = self.editor.get_field_metas(None).await.unwrap(); } - EditorScript::DeleteField { field_meta: field } => { - self.editor.delete_field(&field.id).await.unwrap(); + EditorScript::DeleteField { field_meta } => { + if self.editor.contain_field(&field_meta).await { + self.field_count -= 1; + } + + self.editor.delete_field(&field_meta.id).await.unwrap(); self.field_metas = self.editor.get_field_metas(None).await.unwrap(); + assert_eq!(self.field_count, self.field_metas.len()); } EditorScript::AssertFieldCount(count) => { assert_eq!(self.editor.get_field_metas(None).await.unwrap().len(), count); } - EditorScript::AssertFieldEqual { field_index, field_meta, @@ -220,3 +235,72 @@ pub fn create_single_select_field() -> FieldMeta { .field_type(FieldType::SingleSelect) .build() } + +fn make_template_1_grid() -> BuildGridContext { + let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::default()) + .name("Name") + .visibility(true) + .field_type(FieldType::RichText) + .build(); + + // Single Select + let single_select = SingleSelectTypeOptionsBuilder::default() + .option(SelectOption::new("Live")) + .option(SelectOption::new("Completed")) + .option(SelectOption::new("Planned")) + .option(SelectOption::new("Paused")); + let single_select_field = FieldBuilder::new(single_select) + .name("Status") + .visibility(true) + .field_type(FieldType::SingleSelect) + .build(); + + // MultiSelect + let multi_select = MultiSelectTypeOptionsBuilder::default() + .option(SelectOption::new("Google")) + .option(SelectOption::new("Facebook")) + .option(SelectOption::new("Twitter")); + let multi_select_field = FieldBuilder::new(multi_select) + .name("Platform") + .visibility(true) + .field_type(FieldType::MultiSelect) + .build(); + + // Number + let number = NumberTypeOptionsBuilder::default().set_format(NumberFormat::USD); + let number_field = FieldBuilder::new(number) + .name("Price") + .visibility(true) + .field_type(FieldType::Number) + .build(); + + // Date + let date = DateTypeOptionsBuilder::default() + .date_format(DateFormat::US) + .time_format(TimeFormat::TwentyFourHour); + let date_field = FieldBuilder::new(date) + .name("Time") + .visibility(true) + .field_type(FieldType::DateTime) + .build(); + + // Checkbox + let checkbox = CheckboxTypeOptionsBuilder::default(); + let checkbox_field = FieldBuilder::new(checkbox) + .name("is done") + .visibility(true) + .field_type(FieldType::Checkbox) + .build(); + + GridBuilder::default() + .add_field(text_field) + .add_field(single_select_field) + .add_field(multi_select_field) + .add_field(number_field) + .add_field(date_field) + .add_field(checkbox_field) + .add_empty_row() + .add_empty_row() + .add_empty_row() + .build() +} diff --git a/frontend/rust-lib/flowy-sdk/Cargo.toml b/frontend/rust-lib/flowy-sdk/Cargo.toml index 75791d0279..75ab8a3b5c 100644 --- a/frontend/rust-lib/flowy-sdk/Cargo.toml +++ b/frontend/rust-lib/flowy-sdk/Cargo.toml @@ -12,6 +12,7 @@ flowy-user = { path = "../flowy-user" } flowy-net = { path = "../flowy-net" } flowy-folder = { path = "../flowy-folder", default-features = false } flowy-grid = { path = "../flowy-grid", default-features = false } +flowy-grid-data-model = { path = "../../../shared-lib/flowy-grid-data-model" } flowy-database = { path = "../flowy-database" } flowy-block = { path = "../flowy-block", default-features = false } flowy-sync = { path = "../flowy-sync" } diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs index 0646dbcc5b..89346eaf35 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs @@ -4,6 +4,7 @@ use flowy_collaboration::client_document::default::initial_quill_delta_string; use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; +use flowy_folder::errors::FlowyResult; use flowy_folder::manager::{ViewDataProcessor, ViewDataProcessorMap}; use flowy_folder::prelude::ViewDataType; use flowy_folder::{ @@ -11,8 +12,9 @@ use flowy_folder::{ event_map::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser}, manager::FolderManager, }; -use flowy_grid::manager::GridManager; +use flowy_grid::manager::{make_grid_view_data, GridManager}; use flowy_grid::util::make_default_grid; +use flowy_grid_data_model::entities::BuildGridContext; use flowy_net::ClientServerConfiguration; use flowy_net::{ http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect, @@ -23,6 +25,7 @@ use futures_core::future::BoxFuture; use lib_infra::future::{BoxResultFuture, FutureResult}; use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage}; use std::collections::HashMap; +use std::convert::TryFrom; use std::{convert::TryInto, sync::Arc}; pub struct FolderDepsResolver(); @@ -168,29 +171,39 @@ impl ViewDataProcessor for TextBlockViewDataProcessor { }) } - fn delta_str(&self, view_id: &str) -> FutureResult { + fn delta_bytes(&self, view_id: &str) -> FutureResult { let view_id = view_id.to_string(); let manager = self.0.clone(); FutureResult::new(async move { let editor = manager.open_block(view_id).await?; - let delta_str = editor.delta_str().await?; - Ok(delta_str) + let delta_bytes = Bytes::from(editor.delta_str().await?); + Ok(delta_bytes) }) } - fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult { + fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult { let user_id = user_id.to_string(); let view_id = view_id.to_string(); let manager = self.0.clone(); FutureResult::new(async move { let view_data = initial_quill_delta_string(); - let delta_data = Bytes::from(view_data.clone()); - let repeated_revision: RepeatedRevision = Revision::initial_revision(&user_id, &view_id, delta_data).into(); + let delta_data = Bytes::from(view_data); + let repeated_revision: RepeatedRevision = + Revision::initial_revision(&user_id, &view_id, delta_data.clone()).into(); let _ = manager.create_block(view_id, repeated_revision).await?; - Ok(view_data) + Ok(delta_data) }) } + fn process_create_view_data( + &self, + _user_id: &str, + _view_id: &str, + data: Vec, + ) -> FutureResult { + FutureResult::new(async move { Ok(Bytes::from(data)) }) + } + fn data_type(&self) -> ViewDataType { ViewDataType::TextBlock } @@ -230,36 +243,34 @@ impl ViewDataProcessor for GridViewDataProcessor { }) } - fn delta_str(&self, view_id: &str) -> FutureResult { + fn delta_bytes(&self, view_id: &str) -> FutureResult { let view_id = view_id.to_string(); let grid_manager = self.0.clone(); FutureResult::new(async move { let editor = grid_manager.open_grid(view_id).await?; - let delta_str = editor.delta_str().await; - Ok(delta_str) + let delta_bytes = editor.delta_bytes().await; + Ok(delta_bytes) }) } - fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult { - let info = make_default_grid(view_id); + fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult { + let build_context = make_default_grid(); + let user_id = user_id.to_string(); + let view_id = view_id.to_string(); + let grid_manager = self.0.clone(); + + FutureResult::new(async move { make_grid_view_data(&user_id, &view_id, grid_manager, build_context).await }) + } + + fn process_create_view_data(&self, user_id: &str, view_id: &str, data: Vec) -> FutureResult { let user_id = user_id.to_string(); let view_id = view_id.to_string(); let grid_manager = self.0.clone(); FutureResult::new(async move { - let grid_delta_data = Bytes::from(info.grid_delta.to_delta_str()); - let repeated_revision: RepeatedRevision = - Revision::initial_revision(&user_id, &view_id, grid_delta_data).into(); - let _ = grid_manager.create_grid(&view_id, repeated_revision).await?; - - let block_meta_delta_data = Bytes::from(info.grid_block_meta_delta.to_delta_str()); - let repeated_revision: RepeatedRevision = - Revision::initial_revision(&user_id, &info.block_id, block_meta_delta_data).into(); - let _ = grid_manager - .create_grid_block_meta(&info.block_id, repeated_revision) - .await?; - - Ok(info.grid_delta.to_delta_str()) + let bytes = Bytes::from(data); + let build_context = BuildGridContext::try_from(bytes)?; + make_grid_view_data(&user_id, &view_id, grid_manager, build_context).await }) } diff --git a/frontend/rust-lib/flowy-sync/src/conflict_resolve.rs b/frontend/rust-lib/flowy-sync/src/conflict_resolve.rs index 817b77bd88..a4f4f6c818 100644 --- a/frontend/rust-lib/flowy-sync/src/conflict_resolve.rs +++ b/frontend/rust-lib/flowy-sync/src/conflict_resolve.rs @@ -154,7 +154,7 @@ where &rev_manager.object_id, base_rev_id, rev_id, - client_delta.to_bytes(), + client_delta.to_delta_bytes(), user_id, md5.clone(), ); @@ -166,7 +166,7 @@ where &rev_manager.object_id, base_rev_id, rev_id, - server_delta.to_bytes(), + server_delta.to_delta_bytes(), user_id, md5, ); diff --git a/frontend/rust-lib/flowy-test/src/helper.rs b/frontend/rust-lib/flowy-test/src/helper.rs index 03c4077831..f83f245754 100644 --- a/frontend/rust-lib/flowy-test/src/helper.rs +++ b/frontend/rust-lib/flowy-test/src/helper.rs @@ -26,7 +26,7 @@ pub struct ViewTest { impl ViewTest { #[allow(dead_code)] - pub async fn new(sdk: &FlowySDKTest, data_type: ViewDataType, data: String) -> Self { + pub async fn new(sdk: &FlowySDKTest, data_type: ViewDataType, data: Vec) -> Self { let workspace = create_workspace(sdk, "Workspace", "").await; open_workspace(sdk, &workspace.id).await; let app = create_app(sdk, "App", "AppFlowy GitHub Project", &workspace.id).await; @@ -39,12 +39,12 @@ impl ViewTest { } } - pub async fn new_grid_view(sdk: &FlowySDKTest, data: String) -> Self { + pub async fn new_grid_view(sdk: &FlowySDKTest, data: Vec) -> Self { Self::new(sdk, ViewDataType::Grid, data).await } pub async fn new_text_block_view(sdk: &FlowySDKTest) -> Self { - Self::new(sdk, ViewDataType::TextBlock, "".to_owned()).await + Self::new(sdk, ViewDataType::TextBlock, vec![]).await } } @@ -91,7 +91,7 @@ async fn create_app(sdk: &FlowySDKTest, name: &str, desc: &str, workspace_id: &s app } -async fn create_view(sdk: &FlowySDKTest, app_id: &str, data_type: ViewDataType, data: String) -> View { +async fn create_view(sdk: &FlowySDKTest, app_id: &str, data_type: ViewDataType, data: Vec) -> View { let request = CreateViewPayload { belong_to_id: app_id.to_string(), name: "View A".to_string(), diff --git a/shared-lib/flowy-collaboration/src/client_document/document_pad.rs b/shared-lib/flowy-collaboration/src/client_document/document_pad.rs index 4807d9869c..72b52f6415 100644 --- a/shared-lib/flowy-collaboration/src/client_document/document_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_document/document_pad.rs @@ -6,6 +6,7 @@ use crate::{ }, errors::CollaborateError, }; +use bytes::Bytes; use lib_ot::{ core::*, rich_text::{RichTextAttribute, RichTextDelta}, @@ -62,8 +63,8 @@ impl ClientDocument { self.delta.to_delta_str() } - pub fn to_bytes(&self) -> Vec { - self.delta.clone().to_bytes().to_vec() + pub fn to_bytes(&self) -> Bytes { + self.delta.to_delta_bytes() } pub fn to_plain_string(&self) -> String { diff --git a/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs b/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs index 4fd8a1982e..fd79fb8af0 100644 --- a/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs @@ -268,7 +268,7 @@ impl FolderPad { } pub fn md5(&self) -> String { - md5(&self.delta.to_bytes()) + md5(&self.delta.to_delta_bytes()) } pub fn to_json(&self) -> CollaborateResult { diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index bd8379845a..fafa2d45ce 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -144,7 +144,7 @@ impl GridBlockMetaPad { } pub fn md5(&self) -> String { - md5(&self.delta.to_bytes()) + md5(&self.delta.to_delta_bytes()) } pub fn delta_str(&self) -> String { @@ -165,7 +165,7 @@ pub fn make_block_meta_delta(block_meta: &GridBlockMeta) -> GridBlockMetaDelta { pub fn make_block_meta_revisions(user_id: &str, block_meta: &GridBlockMeta) -> RepeatedRevision { let delta = make_block_meta_delta(block_meta); - let bytes = delta.to_bytes(); + let bytes = delta.to_delta_bytes(); let revision = Revision::initial_revision(user_id, &block_meta.block_id, bytes); revision.into() } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index cbf31463a4..42faa4abda 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -1,66 +1,37 @@ use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBlockMetaDelta, GridMetaDelta}; use crate::errors::{CollaborateError, CollaborateResult}; -use flowy_grid_data_model::entities::{FieldMeta, GridBlock, GridBlockMeta, GridMeta, RowMeta}; +use flowy_grid_data_model::entities::{BuildGridContext, FieldMeta, GridBlock, GridBlockMeta, GridMeta, RowMeta}; pub struct GridBuilder { - grid_id: String, - fields: Vec, - grid_block: GridBlock, - grid_block_meta: GridBlockMeta, + build_context: BuildGridContext, +} + +impl std::default::Default for GridBuilder { + fn default() -> Self { + Self { + build_context: Default::default(), + } + } } impl GridBuilder { - pub fn new(grid_id: &str) -> Self { - let grid_block = GridBlock::new(); - let grid_block_meta = GridBlockMeta { - block_id: grid_block.id.clone(), - rows: vec![], - }; - - Self { - grid_id: grid_id.to_owned(), - fields: vec![], - grid_block, - grid_block_meta, - } - } - pub fn add_field(mut self, field: FieldMeta) -> Self { - self.fields.push(field); + self.build_context.field_metas.push(field); self } pub fn add_empty_row(mut self) -> Self { - let row = RowMeta::new(&self.grid_block.id); - self.grid_block_meta.rows.push(row); - self.grid_block.row_count += 1; + let row = RowMeta::new(&self.build_context.grid_block.id); + self.build_context.grid_block_meta.rows.push(row); + self.build_context.grid_block.row_count += 1; self } - pub fn build(self) -> CollaborateResult { - let block_id = self.grid_block.id.clone(); - let grid_meta = GridMeta { - grid_id: self.grid_id, - fields: self.fields, - blocks: vec![self.grid_block], - }; - // let _ = check_rows(&self.fields, &self.rows)?; - let grid_delta = make_grid_delta(&grid_meta); - let grid_block_meta_delta = make_block_meta_delta(&self.grid_block_meta); - Ok(BuildGridInfo { - grid_delta, - block_id, - grid_block_meta_delta, - }) + pub fn build(self) -> BuildGridContext { + self.build_context } } -pub struct BuildGridInfo { - pub grid_delta: GridMetaDelta, - pub block_id: String, - pub grid_block_meta_delta: GridBlockMetaDelta, -} - #[allow(dead_code)] fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> { let field_ids = fields.iter().map(|field| &field.id).collect::>(); @@ -76,28 +47,31 @@ fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> { #[cfg(test)] mod tests { - use crate::client_grid::GridBuilder; + + use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBuilder}; use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMeta, GridMeta}; #[test] fn create_default_grid_test() { - let info = GridBuilder::new("1") + let grid_id = "1".to_owned(); + let build_context = GridBuilder::default() .add_field(FieldMeta::new("Name", "", FieldType::RichText)) .add_field(FieldMeta::new("Tags", "", FieldType::SingleSelect)) .add_empty_row() .add_empty_row() .add_empty_row() - .build() - .unwrap(); + .build(); - let grid_meta: GridMeta = serde_json::from_str(&info.grid_delta.to_str().unwrap()).unwrap(); - assert_eq!(grid_meta.fields.len(), 2); - assert_eq!(grid_meta.blocks.len(), 1); + let grid_meta = GridMeta { + grid_id: grid_id.clone(), + fields: build_context.field_metas, + blocks: vec![build_context.grid_block], + }; - let grid_block_meta: GridBlockMeta = - serde_json::from_str(&info.grid_block_meta_delta.to_str().unwrap()).unwrap(); - assert_eq!(grid_block_meta.rows.len(), 3); + let grid_meta_delta = make_grid_delta(&grid_meta); + let _: GridMeta = serde_json::from_str(&grid_meta_delta.to_str().unwrap()).unwrap(); - assert_eq!(grid_meta.blocks[0].id, grid_block_meta.block_id); + let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta); + let _: GridBlockMeta = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap(); } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index f303990546..bcae5144a8 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -1,6 +1,7 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; +use bytes::Bytes; use flowy_grid_data_model::entities::{ FieldChangeset, FieldMeta, FieldOrder, GridBlock, GridBlockChangeset, GridMeta, RepeatedFieldOrder, }; @@ -56,6 +57,14 @@ impl GridMetaPad { }) } + pub fn contain_field(&self, field_id: &str) -> bool { + self.grid_meta + .fields + .iter() + .find(|field| &field.id == field_id) + .is_some() + } + pub fn get_field_orders(&self) -> Vec { self.grid_meta .fields @@ -180,13 +189,17 @@ impl GridMetaPad { } pub fn md5(&self) -> String { - md5(&self.delta.to_bytes()) + md5(&self.delta.to_delta_bytes()) } pub fn delta_str(&self) -> String { self.delta.to_delta_str() } + pub fn delta_bytes(&self) -> Bytes { + self.delta.to_delta_bytes() + } + pub fn fields(&self) -> &[FieldMeta] { &self.grid_meta.fields } @@ -258,7 +271,7 @@ pub fn make_grid_delta(grid_meta: &GridMeta) -> GridMetaDelta { pub fn make_grid_revisions(user_id: &str, grid_meta: &GridMeta) -> RepeatedRevision { let delta = make_grid_delta(grid_meta); - let bytes = delta.to_bytes(); + let bytes = delta.to_delta_bytes(); let revision = Revision::initial_revision(user_id, &grid_meta.grid_id, bytes); revision.into() } diff --git a/shared-lib/flowy-folder-data-model/src/entities/view.rs b/shared-lib/flowy-folder-data-model/src/entities/view.rs index bf7b99866c..ac346188ce 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/view.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/view.rs @@ -127,7 +127,7 @@ pub struct CreateViewPayload { pub plugin_type: i32, #[pb(index = 7)] - pub data: String, + pub data: Vec, } #[derive(Default, ProtoBuf, Debug, Clone)] @@ -151,7 +151,7 @@ pub struct CreateViewParams { pub view_id: String, #[pb(index = 7)] - pub data: String, + pub data: Vec, #[pb(index = 8)] pub plugin_type: i32, diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs index 15d8e2feaa..9f19e18f0c 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs +++ b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs @@ -794,7 +794,7 @@ pub struct CreateViewPayload { pub desc: ::std::string::String, pub data_type: ViewDataType, pub plugin_type: i32, - pub data: ::std::string::String, + pub data: ::std::vec::Vec, // message oneof groups pub one_of_thumbnail: ::std::option::Option, // special fields @@ -975,10 +975,10 @@ impl CreateViewPayload { self.plugin_type = v; } - // string data = 7; + // bytes data = 7; - pub fn get_data(&self) -> &str { + pub fn get_data(&self) -> &[u8] { &self.data } pub fn clear_data(&mut self) { @@ -986,19 +986,19 @@ impl CreateViewPayload { } // 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()) } } @@ -1037,7 +1037,7 @@ impl ::protobuf::Message for CreateViewPayload { self.plugin_type = tmp; }, 7 => { - ::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())?; @@ -1067,7 +1067,7 @@ impl ::protobuf::Message for CreateViewPayload { my_size += ::protobuf::rt::value_size(6, self.plugin_type, ::protobuf::wire_format::WireTypeVarint); } if !self.data.is_empty() { - my_size += ::protobuf::rt::string_size(7, &self.data); + my_size += ::protobuf::rt::bytes_size(7, &self.data); } if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail { match v { @@ -1098,7 +1098,7 @@ impl ::protobuf::Message for CreateViewPayload { os.write_int32(6, self.plugin_type)?; } if !self.data.is_empty() { - os.write_string(7, &self.data)?; + os.write_bytes(7, &self.data)?; } if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail { match v { @@ -1175,7 +1175,7 @@ impl ::protobuf::Message for CreateViewPayload { |m: &CreateViewPayload| { &m.plugin_type }, |m: &mut CreateViewPayload| { &mut m.plugin_type }, )); - 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: &CreateViewPayload| { &m.data }, |m: &mut CreateViewPayload| { &mut m.data }, @@ -1228,7 +1228,7 @@ pub struct CreateViewParams { pub thumbnail: ::std::string::String, pub data_type: ViewDataType, pub view_id: ::std::string::String, - pub data: ::std::string::String, + pub data: ::std::vec::Vec, pub plugin_type: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, @@ -1391,10 +1391,10 @@ impl CreateViewParams { ::std::mem::replace(&mut self.view_id, ::std::string::String::new()) } - // string data = 7; + // bytes data = 7; - pub fn get_data(&self) -> &str { + pub fn get_data(&self) -> &[u8] { &self.data } pub fn clear_data(&mut self) { @@ -1402,19 +1402,19 @@ impl CreateViewParams { } // 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()) } // int32 plugin_type = 8; @@ -1461,7 +1461,7 @@ impl ::protobuf::Message for CreateViewParams { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.view_id)?; }, 7 => { - ::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)?; }, 8 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { @@ -1501,7 +1501,7 @@ impl ::protobuf::Message for CreateViewParams { my_size += ::protobuf::rt::string_size(6, &self.view_id); } if !self.data.is_empty() { - my_size += ::protobuf::rt::string_size(7, &self.data); + my_size += ::protobuf::rt::bytes_size(7, &self.data); } if self.plugin_type != 0 { my_size += ::protobuf::rt::value_size(8, self.plugin_type, ::protobuf::wire_format::WireTypeVarint); @@ -1531,7 +1531,7 @@ impl ::protobuf::Message for CreateViewParams { os.write_string(6, &self.view_id)?; } if !self.data.is_empty() { - os.write_string(7, &self.data)?; + os.write_bytes(7, &self.data)?; } if self.plugin_type != 0 { os.write_int32(8, self.plugin_type)?; @@ -1604,7 +1604,7 @@ impl ::protobuf::Message for CreateViewParams { |m: &CreateViewParams| { &m.view_id }, |m: &mut CreateViewParams| { &mut m.view_id }, )); - 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: &CreateViewParams| { &m.data }, |m: &mut CreateViewParams| { &mut m.data }, @@ -2844,22 +2844,22 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x18\x03\x20\x01(\tR\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\0R\ \tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTypeR\x08d\ ataType\x12\x1f\n\x0bplugin_type\x18\x06\x20\x01(\x05R\npluginType\x12\ - \x12\n\x04data\x18\x07\x20\x01(\tR\x04dataB\x12\n\x10one_of_thumbnail\"\ - \xf4\x01\n\x10CreateViewParams\x12\x20\n\x0cbelong_to_id\x18\x01\x20\x01\ - (\tR\nbelongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\ - \x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1c\n\tthumbnail\x18\x04\x20\ - \x01(\tR\tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTy\ - peR\x08dataType\x12\x17\n\x07view_id\x18\x06\x20\x01(\tR\x06viewId\x12\ - \x12\n\x04data\x18\x07\x20\x01(\tR\x04data\x12\x1f\n\x0bplugin_type\x18\ - \x08\x20\x01(\x05R\npluginType\"\x1e\n\x06ViewId\x12\x14\n\x05value\x18\ - \x01\x20\x01(\tR\x05value\"&\n\x0eRepeatedViewId\x12\x14\n\x05items\x18\ - \x01\x20\x03(\tR\x05items\"\xaa\x01\n\x11UpdateViewPayload\x12\x17\n\x07\ - view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\x01(\ - \tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12\ - \x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of_nam\ - eB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail\"\xa9\x01\n\x10UpdateVi\ - ewParams\x12\x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\ - \x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\ + \x12\n\x04data\x18\x07\x20\x01(\x0cR\x04dataB\x12\n\x10one_of_thumbnail\ + \"\xf4\x01\n\x10CreateViewParams\x12\x20\n\x0cbelong_to_id\x18\x01\x20\ + \x01(\tR\nbelongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\ + \x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1c\n\tthumbnail\x18\x04\ + \x20\x01(\tR\tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDa\ + taTypeR\x08dataType\x12\x17\n\x07view_id\x18\x06\x20\x01(\tR\x06viewId\ + \x12\x12\n\x04data\x18\x07\x20\x01(\x0cR\x04data\x12\x1f\n\x0bplugin_typ\ + e\x18\x08\x20\x01(\x05R\npluginType\"\x1e\n\x06ViewId\x12\x14\n\x05value\ + \x18\x01\x20\x01(\tR\x05value\"&\n\x0eRepeatedViewId\x12\x14\n\x05items\ + \x18\x01\x20\x03(\tR\x05items\"\xaa\x01\n\x11UpdateViewPayload\x12\x17\n\ + \x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\ + \x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\ + \x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of\ + _nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail\"\xa9\x01\n\x10Upda\ + teViewParams\x12\x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\ + \n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\ \x01(\tH\x01R\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthu\ mbnailB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnai\ l*'\n\x0cViewDataType\x12\r\n\tTextBlock\x10\0\x12\x08\n\x04Grid\x10\x01\ diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto index b66f778a71..56e09c54e4 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto +++ b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto @@ -24,7 +24,7 @@ message CreateViewPayload { oneof one_of_thumbnail { string thumbnail = 4; }; ViewDataType data_type = 5; int32 plugin_type = 6; - string data = 7; + bytes data = 7; } message CreateViewParams { string belong_to_id = 1; @@ -33,7 +33,7 @@ message CreateViewParams { string thumbnail = 4; ViewDataType data_type = 5; string view_id = 6; - string data = 7; + bytes data = 7; int32 plugin_type = 8; } message ViewId { diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index c7cd8338c8..f8c762345d 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -1,7 +1,8 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; -use strum_macros::{Display, EnumIter, EnumString}; +use strum::{EnumCount, IntoEnumIterator}; +use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 36; pub const DEFAULT_FIELD_WIDTH: i32 = 150; @@ -139,7 +140,9 @@ pub struct FieldChangeset { pub type_options: Option, } -#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)] +#[derive( + Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumCountMacro, EnumString, EnumIter, Display, Serialize, Deserialize, +)] pub enum FieldType { RichText = 0, Number = 1, @@ -312,3 +315,31 @@ impl std::convert::From for RowMetaChangeset { } } } + +#[derive(Clone, ProtoBuf)] +pub struct BuildGridContext { + #[pb(index = 1)] + pub field_metas: Vec, + + #[pb(index = 2)] + pub grid_block: GridBlock, + + #[pb(index = 3)] + pub grid_block_meta: GridBlockMeta, +} + +impl std::default::Default for BuildGridContext { + fn default() -> Self { + let grid_block = GridBlock::new(); + let grid_block_meta = GridBlockMeta { + block_id: grid_block.id.clone(), + rows: vec![], + }; + + Self { + field_metas: vec![], + grid_block, + grid_block_meta, + } + } +} diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index bd01ee6cf6..9a90b67f81 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -3073,6 +3073,286 @@ impl ::protobuf::reflect::ProtobufValue for CellMetaChangeset { } } +#[derive(PartialEq,Clone,Default)] +pub struct BuildGridContext { + // message fields + pub field_metas: ::protobuf::RepeatedField, + pub grid_block: ::protobuf::SingularPtrField, + pub grid_block_meta: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a BuildGridContext { + fn default() -> &'a BuildGridContext { + ::default_instance() + } +} + +impl BuildGridContext { + pub fn new() -> BuildGridContext { + ::std::default::Default::default() + } + + // repeated .FieldMeta field_metas = 1; + + + pub fn get_field_metas(&self) -> &[FieldMeta] { + &self.field_metas + } + pub fn clear_field_metas(&mut self) { + self.field_metas.clear(); + } + + // Param is passed by value, moved + pub fn set_field_metas(&mut self, v: ::protobuf::RepeatedField) { + self.field_metas = v; + } + + // Mutable pointer to the field. + pub fn mut_field_metas(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.field_metas + } + + // Take field + pub fn take_field_metas(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.field_metas, ::protobuf::RepeatedField::new()) + } + + // .GridBlock grid_block = 2; + + + pub fn get_grid_block(&self) -> &GridBlock { + self.grid_block.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_grid_block(&mut self) { + self.grid_block.clear(); + } + + pub fn has_grid_block(&self) -> bool { + self.grid_block.is_some() + } + + // Param is passed by value, moved + pub fn set_grid_block(&mut self, v: GridBlock) { + self.grid_block = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_block(&mut self) -> &mut GridBlock { + if self.grid_block.is_none() { + self.grid_block.set_default(); + } + self.grid_block.as_mut().unwrap() + } + + // Take field + pub fn take_grid_block(&mut self) -> GridBlock { + self.grid_block.take().unwrap_or_else(|| GridBlock::new()) + } + + // .GridBlockMeta grid_block_meta = 3; + + + pub fn get_grid_block_meta(&self) -> &GridBlockMeta { + self.grid_block_meta.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_grid_block_meta(&mut self) { + self.grid_block_meta.clear(); + } + + pub fn has_grid_block_meta(&self) -> bool { + self.grid_block_meta.is_some() + } + + // Param is passed by value, moved + pub fn set_grid_block_meta(&mut self, v: GridBlockMeta) { + self.grid_block_meta = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_block_meta(&mut self) -> &mut GridBlockMeta { + if self.grid_block_meta.is_none() { + self.grid_block_meta.set_default(); + } + self.grid_block_meta.as_mut().unwrap() + } + + // Take field + pub fn take_grid_block_meta(&mut self) -> GridBlockMeta { + self.grid_block_meta.take().unwrap_or_else(|| GridBlockMeta::new()) + } +} + +impl ::protobuf::Message for BuildGridContext { + fn is_initialized(&self) -> bool { + for v in &self.field_metas { + if !v.is_initialized() { + return false; + } + }; + for v in &self.grid_block { + if !v.is_initialized() { + return false; + } + }; + for v in &self.grid_block_meta { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.field_metas)?; + }, + 2 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block)?; + }, + 3 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block_meta)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.field_metas { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + if let Some(ref v) = self.grid_block.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if let Some(ref v) = self.grid_block_meta.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.field_metas { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + if let Some(ref v) = self.grid_block.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if let Some(ref v) = self.grid_block_meta.as_ref() { + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> BuildGridContext { + BuildGridContext::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "field_metas", + |m: &BuildGridContext| { &m.field_metas }, + |m: &mut BuildGridContext| { &mut m.field_metas }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "grid_block", + |m: &BuildGridContext| { &m.grid_block }, + |m: &mut BuildGridContext| { &mut m.grid_block }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "grid_block_meta", + |m: &BuildGridContext| { &m.grid_block_meta }, + |m: &mut BuildGridContext| { &mut m.grid_block_meta }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "BuildGridContext", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static BuildGridContext { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(BuildGridContext::new) + } +} + +impl ::protobuf::Clear for BuildGridContext { + fn clear(&mut self) { + self.field_metas.clear(); + self.grid_block.clear(); + self.grid_block_meta.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for BuildGridContext { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for BuildGridContext { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum FieldType { RichText = 0, @@ -3178,10 +3458,13 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ata\x18\x02\x20\x01(\tR\x04data\"j\n\x11CellMetaChangeset\x12\x15\n\x06r\ ow_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x02\x20\x01\ (\tR\x07fieldId\x12\x14\n\x04data\x18\x03\x20\x01(\tH\0R\x04dataB\r\n\ - \x0bone_of_data*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Nu\ - mber\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\ - \x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06\ - proto3\ + \x0bone_of_data\"\xa2\x01\n\x10BuildGridContext\x12+\n\x0bfield_metas\ + \x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12)\n\ngrid_block\x18\ + \x02\x20\x01(\x0b2\n.GridBlockR\tgridBlock\x126\n\x0fgrid_block_meta\x18\ + \x03\x20\x01(\x0b2\x0e.GridBlockMetaR\rgridBlockMeta*d\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\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 32fc3896ac..12447f6e8f 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -60,6 +60,11 @@ message CellMetaChangeset { string field_id = 2; oneof one_of_data { string data = 3; }; } +message BuildGridContext { + repeated FieldMeta field_metas = 1; + GridBlock grid_block = 2; + GridBlockMeta grid_block_meta = 3; +} enum FieldType { RichText = 0; Number = 1; diff --git a/shared-lib/lib-ot/src/core/delta/delta.rs b/shared-lib/lib-ot/src/core/delta/delta.rs index ac4fcbbef5..29fd424dcb 100644 --- a/shared-lib/lib-ot/src/core/delta/delta.rs +++ b/shared-lib/lib-ot/src/core/delta/delta.rs @@ -529,7 +529,7 @@ where self.apply("") } - pub fn to_bytes(&self) -> Bytes { + pub fn to_delta_bytes(&self) -> Bytes { let json = self.to_delta_str(); Bytes::from(json.into_bytes()) } From b3ed254cafe681c466e19ac45c46b114a1e3055a Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 16 Mar 2022 10:02:37 +0800 Subject: [PATCH 22/28] chore: add more test and fix warnings --- frontend/rust-lib/flowy-error/src/errors.rs | 2 + .../flowy-folder/tests/workspace/script.rs | 2 +- .../rust-lib/flowy-grid/src/event_handler.rs | 6 +- frontend/rust-lib/flowy-grid/src/manager.rs | 6 +- .../src/services/block_meta_editor.rs | 4 +- .../cell/description/date_description.rs | 11 +- .../cell/description/number_description.rs | 21 ++- .../cell/description/selection_description.rs | 49 +++-- .../cell/description/text_description.rs | 7 +- .../flowy-grid/src/services/grid_editor.rs | 27 ++- .../src/services/row/row_builder.rs | 31 +++- .../flowy-grid/tests/grid/grid_test.rs | 168 ++++++++++++++++-- .../rust-lib/flowy-grid/tests/grid/script.rs | 18 +- .../flowy-sdk/src/deps_resolve/folder_deps.rs | 2 +- .../src/client_grid/block_pad.rs | 2 +- .../src/client_grid/grid_builder.rs | 14 +- .../{grid_pad.rs => grid_meta_pad.rs} | 18 +- .../src/client_grid/mod.rs | 4 +- shared-lib/flowy-error-code/src/code.rs | 4 + .../src/protobuf/model/code.rs | 13 +- .../src/protobuf/proto/code.proto | 2 + .../src/entities/view.rs | 2 +- .../src/entities/meta.rs | 6 +- shared-lib/lib-infra/src/future.rs | 31 ---- 24 files changed, 318 insertions(+), 132 deletions(-) rename shared-lib/flowy-collaboration/src/client_grid/{grid_pad.rs => grid_meta_pad.rs} (95%) diff --git a/frontend/rust-lib/flowy-error/src/errors.rs b/frontend/rust-lib/flowy-error/src/errors.rs index 956df16fa5..cd890fd02e 100644 --- a/frontend/rust-lib/flowy-error/src/errors.rs +++ b/frontend/rust-lib/flowy-error/src/errors.rs @@ -64,6 +64,8 @@ impl FlowyError { static_flowy_error!(name_empty, ErrorCode::UserNameIsEmpty); static_flowy_error!(user_id, ErrorCode::UserIdInvalid); static_flowy_error!(user_not_exist, ErrorCode::UserNotExist); + static_flowy_error!(text_too_long, ErrorCode::TextTooLong); + static_flowy_error!(invalid_data, ErrorCode::InvalidData); } impl std::convert::From for FlowyError { diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index 3cb65a414c..e476c36f2d 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs @@ -351,7 +351,7 @@ pub async fn create_view(sdk: &FlowySDKTest, app_id: &str, name: &str, desc: &st thumbnail: None, data_type, plugin_type: 0, - data: "".to_string(), + data: vec![], }; let view = FolderEventBuilder::new(sdk.clone()) .event(CreateView) diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 5028a40407..28e25854d0 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -36,11 +36,7 @@ pub(crate) async fn get_fields_handler( let payload: QueryFieldPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; let field_metas = editor.get_field_metas(Some(payload.field_orders)).await?; - let repeated_field: RepeatedField = field_metas - .into_iter() - .map(|field_meta| Field::from(field_meta)) - .collect::>() - .into(); + let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::>().into(); data_result(repeated_field) } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 28a246bd75..fde6d136f2 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -111,8 +111,7 @@ impl GridManager { ) -> Result, FlowyError> { let user = self.grid_user.clone(); let rev_manager = self.make_grid_rev_manager(grid_id, pool.clone())?; - let kv_persistence = self.get_kv_persistence()?; - let grid_editor = ClientGridEditor::new(grid_id, user, rev_manager, kv_persistence).await?; + let grid_editor = ClientGridEditor::new(grid_id, user, rev_manager).await?; Ok(grid_editor) } @@ -137,6 +136,7 @@ impl GridManager { Ok(rev_manager) } + #[allow(dead_code)] fn get_kv_persistence(&self) -> FlowyResult> { let read_guard = self.kv_persistence.read(); if read_guard.is_some() { @@ -198,7 +198,7 @@ pub async fn make_grid_view_data( let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta); let block_meta_delta_data = grid_block_meta_delta.to_delta_bytes(); let repeated_revision: RepeatedRevision = - Revision::initial_revision(&user_id, &block_id, block_meta_delta_data).into(); + Revision::initial_revision(user_id, &block_id, block_meta_delta_data).into(); let _ = grid_manager .create_grid_block_meta(&block_id, repeated_revision) .await?; 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 fb72f8c34d..f0d0b8e475 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 @@ -139,7 +139,7 @@ impl GridBlockMetaEditorManager { for grid_block in grid_blocks { let editor = self.get_editor(&grid_block.id).await?; let row_metas = editor.get_row_metas(None).await?; - let block_row_orders = row_metas.iter().map(|row_meta| RowOrder::from(row_meta)); + let block_row_orders = row_metas.iter().map(RowOrder::from); row_orders.extend(block_row_orders); } Ok(row_orders) @@ -257,7 +257,7 @@ impl ClientGridBlockMetaEditor { .await .get_rows(None)? .iter() - .map(|row_meta| RowOrder::from(row_meta)) + .map(RowOrder::from) .collect::>(); Ok(row_orders) } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs index 1b057b5314..30af0fb160 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/date_description.rs @@ -53,14 +53,11 @@ impl CellDataSerde for DateDescription { } fn serialize_cell_data(&self, data: &str) -> Result { - let timestamp = match data.parse::() { - Ok(timestamp) => timestamp, - Err(e) => { - tracing::error!("Parse {} to i64 failed: {}", data, e); - chrono::Utc::now().timestamp() - } + if let Err(e) = data.parse::() { + tracing::error!("Parse {} to i64 failed: {}", data, e); + return Err(FlowyError::internal().context(e)); }; - Ok(format!("{}", timestamp)) + Ok(data.to_owned()) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs index a4a3c08d90..c3468786df 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/number_description.rs @@ -93,7 +93,7 @@ impl NumberDescription { } fn decimal_from_str(&self, s: &str) -> Decimal { - let mut decimal = Decimal::from_str(s).unwrap_or(Decimal::zero()); + let mut decimal = Decimal::from_str(s).unwrap_or_else(|_| Decimal::zero()); match decimal.set_scale(self.scale) { Ok(_) => {} Err(e) => { @@ -130,7 +130,12 @@ impl CellDataSerde for NumberDescription { } fn serialize_cell_data(&self, data: &str) -> Result { - Ok(self.strip_symbol(data)) + let data = self.strip_symbol(data); + + if !data.chars().all(char::is_numeric) { + return Err(FlowyError::invalid_data().context("Should only contain numbers")); + } + Ok(data) } } @@ -188,8 +193,10 @@ mod tests { #[test] fn number_description_scale_test() { - let mut description = NumberDescription::default(); - description.scale = 1; + let mut description = NumberDescription { + scale: 1, + ..Default::default() + }; for format in NumberFormat::iter() { description.format = format; @@ -224,8 +231,10 @@ mod tests { #[test] fn number_description_sign_test() { - let mut description = NumberDescription::default(); - description.sign_positive = false; + let mut description = NumberDescription { + sign_positive: false, + ..Default::default() + }; for format in NumberFormat::iter() { description.format = format; diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs index 2f772c3c5d..0115e390dd 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/selection_description.rs @@ -2,9 +2,13 @@ use crate::impl_from_and_to_type_option; use crate::services::row::CellDataSerde; use crate::services::util::*; use flowy_derive::ProtoBuf; -use flowy_error::FlowyError; +use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{FieldMeta, FieldType}; +use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +pub const SELECTION_IDS_SEPARATOR: &str = ","; // Single select #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] @@ -23,7 +27,7 @@ impl CellDataSerde for SingleSelectDescription { } fn serialize_cell_data(&self, data: &str) -> Result { - Ok(select_option_id_from_data(data.to_owned(), true)) + single_select_option_id_from_data(data.to_owned()) } } @@ -43,20 +47,45 @@ impl CellDataSerde for MultiSelectDescription { } fn serialize_cell_data(&self, data: &str) -> Result { - Ok(select_option_id_from_data(data.to_owned(), false)) + multi_select_option_id_from_data(data.to_owned()) } } -fn select_option_id_from_data(data: String, is_single_select: bool) -> String { - if !is_single_select { - return data; - } - let select_option_ids = data.split(',').collect::>(); +fn single_select_option_id_from_data(data: String) -> FlowyResult { + let select_option_ids = select_option_ids(data)?; if select_option_ids.is_empty() { - return "".to_owned(); + return Ok("".to_owned()); } - select_option_ids.split_first().unwrap().0.to_string() + Ok(select_option_ids.split_first().unwrap().0.to_string()) +} + +fn multi_select_option_id_from_data(data: String) -> FlowyResult { + let select_option_ids = select_option_ids(data)?; + Ok(select_option_ids.join(SELECTION_IDS_SEPARATOR)) +} + +fn select_option_ids(mut data: String) -> FlowyResult> { + data.retain(|c| !c.is_whitespace()); + let select_option_ids = data.split(SELECTION_IDS_SEPARATOR).collect::>(); + if select_option_ids + .par_iter() + .find_first(|option_id| match Uuid::parse_str(option_id) { + Ok(_) => false, + Err(e) => { + tracing::error!("{}", e); + true + } + }) + .is_some() + { + let msg = format!( + "Invalid selection id string: {}. It should consist of the uuid string and separated by comma", + data + ); + return Err(FlowyError::internal().context(msg)); + } + Ok(select_option_ids.iter().map(|id| id.to_string()).collect::>()) } #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs index 1f71244519..539b82402c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/description/text_description.rs @@ -19,6 +19,11 @@ impl CellDataSerde for RichTextDescription { } fn serialize_cell_data(&self, data: &str) -> Result { - Ok(data.to_owned()) + let data = data.to_owned(); + if data.len() > 10000 { + Err(FlowyError::text_too_long().context("The len of the text should not be more than 10000")) + } else { + Ok(data) + } } } 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 86c7a8fc0e..9436b62e6f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,19 +1,19 @@ use crate::manager::GridUser; use crate::services::block_meta_editor::GridBlockMetaEditorManager; -use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use bytes::Bytes; use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, + CellMetaChangeset, FieldChangeset, FieldMeta, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, }; use std::collections::HashMap; use crate::services::row::{ - make_row_by_row_id, make_rows, row_meta_from_context, CreateRowContext, CreateRowContextBuilder, + make_row_by_row_id, make_rows, row_meta_from_context, serialize_cell_data, CreateRowContext, + CreateRowContextBuilder, }; use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; @@ -27,7 +27,6 @@ pub struct ClientGridEditor { grid_meta_pad: Arc>, rev_manager: Arc, block_meta_manager: Arc, - kv_persistence: Arc, } impl ClientGridEditor { @@ -35,7 +34,6 @@ impl ClientGridEditor { grid_id: &str, user: Arc, mut rev_manager: RevisionManager, - kv_persistence: Arc, ) -> FlowyResult> { let token = user.token()?; let cloud = Arc::new(GridRevisionCloudService { token }); @@ -52,7 +50,6 @@ impl ClientGridEditor { grid_meta_pad, rev_manager, block_meta_manager, - kv_persistence, })) } @@ -88,7 +85,8 @@ impl ClientGridEditor { pub async fn create_row(&self) -> FlowyResult<()> { let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?; let block_id = self.last_block_id().await?; - let row = row_meta_from_context(&block_id, CreateRowContextBuilder::new(&field_metas).build()); + let create_row_ctx = CreateRowContextBuilder::new(&field_metas).build(); + let row = row_meta_from_context(&block_id, create_row_ctx); let row_count = self.block_meta_manager.create_row(row).await?; let changeset = GridBlockChangeset::from_row_count(&block_id, row_count); let _ = self.update_block(changeset).await?; @@ -98,12 +96,11 @@ impl ClientGridEditor { pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult<()> { let block_id = self.last_block_id().await?; let mut rows_by_block_id: HashMap> = HashMap::new(); - for ctx in contexts { let row_meta = row_meta_from_context(&block_id, ctx); rows_by_block_id .entry(block_id.clone()) - .or_insert(Vec::new()) + .or_insert_with(Vec::new) .push(row_meta); } let changesets = self.block_meta_manager.insert_row(rows_by_block_id).await?; @@ -118,6 +115,18 @@ impl ClientGridEditor { } pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> { + if let Some(cell_data) = changeset.data.as_ref() { + match self.grid_meta_pad.read().await.get_field(&changeset.field_id) { + None => { + return Err(FlowyError::internal() + .context(format!("Can not find the field with id: {}", &changeset.field_id))); + } + Some(field_meta) => { + let _ = serialize_cell_data(cell_data, field_meta)?; + } + } + } + let row_changeset: RowMetaChangeset = changeset.into(); self.update_row(row_changeset).await } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index 6bc231293a..676411e8c7 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -1,28 +1,43 @@ +use crate::services::row::serialize_cell_data; +use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT}; use std::collections::HashMap; pub struct CreateRowContextBuilder<'a> { - #[allow(dead_code)] - fields: &'a [FieldMeta], + field_meta_map: HashMap<&'a String, &'a FieldMeta>, ctx: CreateRowContext, } impl<'a> CreateRowContextBuilder<'a> { pub fn new(fields: &'a [FieldMeta]) -> Self { + let field_meta_map = fields + .iter() + .map(|field| (&field.id, field)) + .collect::>(); + let ctx = CreateRowContext { row_id: uuid::Uuid::new_v4().to_string(), cell_by_field_id: Default::default(), height: DEFAULT_ROW_HEIGHT, visibility: true, }; - Self { fields, ctx } + + Self { field_meta_map, ctx } } - #[allow(dead_code)] - pub fn add_cell(mut self, field_id: &str, data: String) -> Self { - let cell = CellMeta::new(field_id, data); - self.ctx.cell_by_field_id.insert(field_id.to_owned(), cell); - self + pub fn add_cell(&mut self, field_id: &str, data: String) -> FlowyResult<()> { + match self.field_meta_map.get(&field_id.to_owned()) { + None => { + let msg = format!("Invalid field_id: {}", field_id); + Err(FlowyError::internal().context(msg)) + } + Some(field_meta) => { + let data = serialize_cell_data(&data, field_meta)?; + let cell = CellMeta::new(field_id, data); + self.ctx.cell_by_field_id.insert(field_id.to_owned(), cell); + Ok(()) + } + } } #[allow(dead_code)] 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 30469d406f..acb8e27c39 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -1,8 +1,11 @@ use crate::grid::script::EditorScript::*; use crate::grid::script::*; +use chrono::NaiveDateTime; use flowy_grid::services::cell::*; use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, CreateRowContextBuilder}; -use flowy_grid_data_model::entities::{FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMetaChangeset}; +use flowy_grid_data_model::entities::{ + CellMetaChangeset, FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMetaChangeset, +}; #[tokio::test] async fn grid_create_field() { @@ -237,29 +240,28 @@ async fn grid_delete_row() { } #[tokio::test] -async fn grid_update_cell() { +async fn grid_row_add_cells_test() { let mut test = GridEditorTest::new().await; let mut builder = CreateRowContextBuilder::new(&test.field_metas); for field in &test.field_metas { match field.field_type { FieldType::RichText => { let data = serialize_cell_data("hello world", field).unwrap(); - builder = builder.add_cell(&field.id, data); + builder.add_cell(&field.id, data).unwrap(); } FieldType::Number => { let data = serialize_cell_data("¥18,443", field).unwrap(); - builder = builder.add_cell(&field.id, data); + builder.add_cell(&field.id, data).unwrap(); } FieldType::DateTime => { let data = serialize_cell_data("1647251762", field).unwrap(); - builder = builder.add_cell(&field.id, data); + builder.add_cell(&field.id, data).unwrap(); } FieldType::SingleSelect => { let description = SingleSelectDescription::from(field); let options = description.options.first().unwrap(); - let data = description.serialize_cell_data(&options.id).unwrap(); - builder = builder.add_cell(&field.id, data); + builder.add_cell(&field.id, data).unwrap(); } FieldType::MultiSelect => { let description = MultiSelectDescription::from(field); @@ -268,17 +270,161 @@ async fn grid_update_cell() { .iter() .map(|option| option.id.clone()) .collect::>() - .join(","); + .join(SELECTION_IDS_SEPARATOR); let data = description.serialize_cell_data(&options).unwrap(); - builder = builder.add_cell(&field.id, data); + builder.add_cell(&field.id, data).unwrap(); } FieldType::Checkbox => { let data = serialize_cell_data("false", field).unwrap(); - builder = builder.add_cell(&field.id, data); + builder.add_cell(&field.id, data).unwrap(); } } } let context = builder.build(); - let scripts = vec![AssertRowCount(3), CreateRow { context }, AssertGridMetaPad]; + let scripts = vec![CreateRow { context }, AssertGridMetaPad]; + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_row_add_selection_cell_test() { + let mut test = GridEditorTest::new().await; + let mut builder = CreateRowContextBuilder::new(&test.field_metas); + let uuid = uuid::Uuid::new_v4().to_string(); + let mut single_select_field_id = "".to_string(); + let mut multi_select_field_id = "".to_string(); + for field in &test.field_metas { + match field.field_type { + FieldType::SingleSelect => { + single_select_field_id = field.id.clone(); + // The element must be parsed as uuid + assert!(builder.add_cell(&field.id, "data".to_owned()).is_err()); + // // The data should not be empty + assert!(builder.add_cell(&field.id, "".to_owned()).is_err()); + // The element must be parsed as uuid + assert!(builder.add_cell(&field.id, "1,2,3".to_owned()).is_err(),); + // The separator must be comma + assert!(builder.add_cell(&field.id, format!("{}. {}", &uuid, &uuid),).is_err()); + // + + assert!(builder.add_cell(&field.id, uuid.clone()).is_ok()); + assert!(builder.add_cell(&field.id, format!("{}, {}", &uuid, &uuid)).is_ok()); + } + FieldType::MultiSelect => { + multi_select_field_id = field.id.clone(); + assert!(builder.add_cell(&field.id, format!("{}, {}", &uuid, &uuid)).is_ok()); + } + _ => {} + } + } + let context = builder.build(); + assert_eq!( + &context + .cell_by_field_id + .get(&single_select_field_id) + .as_ref() + .unwrap() + .data, + &uuid + ); + assert_eq!( + context + .cell_by_field_id + .get(&multi_select_field_id) + .as_ref() + .unwrap() + .data, + format!("{},{}", &uuid, &uuid) + ); + + let scripts = vec![CreateRow { context }]; + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_row_add_date_cell_test() { + let mut test = GridEditorTest::new().await; + let mut builder = CreateRowContextBuilder::new(&test.field_metas); + let mut date_field = None; + let timestamp = 1647390674; + for field in &test.field_metas { + if field.field_type == FieldType::DateTime { + date_field = Some(field.clone()); + NaiveDateTime::from_timestamp(123, 0); + // The data should not be empty + assert!(builder.add_cell(&field.id, "".to_owned()).is_err()); + + assert!(builder.add_cell(&field.id, "123".to_owned()).is_ok()); + assert!(builder.add_cell(&field.id, format!("{}", timestamp)).is_ok()); + } + } + let context = builder.build(); + let date_field = date_field.unwrap(); + let cell_data = context.cell_by_field_id.get(&date_field.id).unwrap().clone(); + assert_eq!( + deserialize_cell_data(cell_data.data.clone(), &date_field).unwrap(), + "2022/03/16 08:31", + ); + let scripts = vec![CreateRow { context }]; + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn grid_cell_update() { + let mut test = GridEditorTest::new().await; + let field_metas = &test.field_metas; + let row_metas = &test.row_metas; + assert_eq!(row_metas.len(), 3); + + let mut scripts = vec![]; + for (index, row_meta) in row_metas.iter().enumerate() { + for field_meta in field_metas { + if index == 0 { + let data = match field_meta.field_type { + FieldType::RichText => "".to_string(), + FieldType::Number => "123".to_string(), + FieldType::DateTime => "123".to_string(), + FieldType::SingleSelect => { + let description = SingleSelectDescription::from(field_meta); + description.options.first().unwrap().id.clone() + } + FieldType::MultiSelect => { + let description = MultiSelectDescription::from(field_meta); + description.options.first().unwrap().id.clone() + } + FieldType::Checkbox => "1".to_string(), + }; + + scripts.push(UpdateCell { + changeset: CellMetaChangeset { + row_id: row_meta.id.clone(), + field_id: field_meta.id.clone(), + data: Some(data), + }, + is_err: false, + }); + } + + if index == 1 { + let (data, is_err) = match field_meta.field_type { + FieldType::RichText => ("1".to_string().repeat(10001), true), + FieldType::Number => ("abc".to_string(), true), + FieldType::DateTime => ("abc".to_string(), true), + FieldType::SingleSelect => ("abc".to_string(), true), + FieldType::MultiSelect => ("abc".to_string(), true), + FieldType::Checkbox => ("2".to_string(), false), + }; + + scripts.push(UpdateCell { + changeset: CellMetaChangeset { + row_id: row_meta.id.clone(), + field_id: field_meta.id.clone(), + data: Some(data), + }, + is_err, + }); + } + } + } + test.run_scripts(scripts).await; } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index c49bf82a03..2c784153be 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,8 +1,6 @@ use bytes::Bytes; use flowy_collaboration::client_grid::GridBuilder; -use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; -use flowy_error::FlowyResult; -use flowy_grid::manager::{make_grid_view_data, GridManager}; + use flowy_grid::services::cell::*; use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; @@ -16,7 +14,7 @@ use flowy_test::helper::ViewTest; use flowy_test::FlowySDKTest; use std::sync::Arc; use std::time::Duration; -use strum::{EnumCount, IntoEnumIterator}; +use strum::EnumCount; use tokio::time::sleep; pub enum EditorScript { @@ -65,6 +63,7 @@ pub enum EditorScript { }, UpdateCell { changeset: CellMetaChangeset, + is_err: bool, }, AssertRowCount(usize), // AssertRowEqual{ row_index: usize, row: RowMeta}, @@ -199,9 +198,14 @@ impl GridEditorTest { assert_eq!(row.height, height); } } - EditorScript::UpdateCell { changeset } => { - self.editor.update_cell(changeset).await.unwrap(); - self.row_metas = self.editor.get_row_metas(None).await.unwrap(); + EditorScript::UpdateCell { changeset, is_err } => { + let result = self.editor.update_cell(changeset).await; + if is_err { + assert!(result.is_err()) + } else { + let _ = result.unwrap(); + self.row_metas = self.editor.get_row_metas(None).await.unwrap(); + } } EditorScript::AssertRowCount(count) => { assert_eq!(self.editor.get_rows(None).await.unwrap().len(), count); diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs index 89346eaf35..6ed3df3207 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs @@ -4,7 +4,7 @@ use flowy_collaboration::client_document::default::initial_quill_delta_string; use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; -use flowy_folder::errors::FlowyResult; + use flowy_folder::manager::{ViewDataProcessor, ViewDataProcessorMap}; use flowy_folder::prelude::ViewDataType; use flowy_folder::{ diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index fafa2d45ce..840e4c28af 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -52,7 +52,7 @@ impl GridBlockMetaPad { pub fn get_rows(&self, row_ids: Option>) -> CollaborateResult>> { match row_ids { - None => Ok(self.rows.iter().map(|row| row.clone()).collect::>()), + None => Ok(self.rows.to_vec()), Some(row_ids) => { let row_map = self .rows diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index 42faa4abda..a6be909ef6 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -1,19 +1,11 @@ -use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBlockMetaDelta, GridMetaDelta}; use crate::errors::{CollaborateError, CollaborateResult}; -use flowy_grid_data_model::entities::{BuildGridContext, FieldMeta, GridBlock, GridBlockMeta, GridMeta, RowMeta}; +use flowy_grid_data_model::entities::{BuildGridContext, FieldMeta, RowMeta}; +#[derive(Default)] pub struct GridBuilder { build_context: BuildGridContext, } -impl std::default::Default for GridBuilder { - fn default() -> Self { - Self { - build_context: Default::default(), - } - } -} - impl GridBuilder { pub fn add_field(mut self, field: FieldMeta) -> Self { self.build_context.field_metas.push(field); @@ -63,7 +55,7 @@ mod tests { .build(); let grid_meta = GridMeta { - grid_id: grid_id.clone(), + grid_id, fields: build_context.field_metas, blocks: vec![build_context.grid_block], }; diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs similarity index 95% rename from shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs rename to shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs index bcae5144a8..e836034fae 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs @@ -58,19 +58,15 @@ impl GridMetaPad { } pub fn contain_field(&self, field_id: &str) -> bool { - self.grid_meta - .fields - .iter() - .find(|field| &field.id == field_id) - .is_some() + self.grid_meta.fields.iter().any(|field| field.id == field_id) + } + + pub fn get_field(&self, field_id: &str) -> Option<&FieldMeta> { + self.grid_meta.fields.iter().find(|field| field.id == field_id) } pub fn get_field_orders(&self) -> Vec { - self.grid_meta - .fields - .iter() - .map(|field_meta| FieldOrder::from(field_meta)) - .collect() + self.grid_meta.fields.iter().map(FieldOrder::from).collect() } pub fn get_field_metas(&self, field_orders: Option) -> CollaborateResult> { @@ -154,7 +150,7 @@ impl GridMetaPad { if last_block.start_row_index > block.start_row_index && last_block.len() > block.start_row_index { - let msg = format!("GridBlock's start_row_index should be greater than the last_block's start_row_index and its len"); + let msg = "GridBlock's start_row_index should be greater than the last_block's start_row_index and its len".to_string(); return Err(CollaborateError::internal().context(msg)) } grid.blocks.push(block); diff --git a/shared-lib/flowy-collaboration/src/client_grid/mod.rs b/shared-lib/flowy-collaboration/src/client_grid/mod.rs index 5fbaa170b4..9dcb155557 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/mod.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/mod.rs @@ -1,7 +1,7 @@ mod block_pad; mod grid_builder; -mod grid_pad; +mod grid_meta_pad; pub use block_pad::*; pub use grid_builder::*; -pub use grid_pad::*; +pub use grid_meta_pad::*; diff --git a/shared-lib/flowy-error-code/src/code.rs b/shared-lib/flowy-error-code/src/code.rs index c47d4fd8d4..166202bd5b 100644 --- a/shared-lib/flowy-error-code/src/code.rs +++ b/shared-lib/flowy-error-code/src/code.rs @@ -83,6 +83,10 @@ pub enum ErrorCode { UserIdInvalid = 311, #[display(fmt = "User not exist")] UserNotExist = 312, + #[display(fmt = "Text is too long")] + TextTooLong = 400, + #[display(fmt = "Invalid data")] + InvalidData = 401, } impl ErrorCode { diff --git a/shared-lib/flowy-error-code/src/protobuf/model/code.rs b/shared-lib/flowy-error-code/src/protobuf/model/code.rs index f70c1eb49d..769c059eb2 100644 --- a/shared-lib/flowy-error-code/src/protobuf/model/code.rs +++ b/shared-lib/flowy-error-code/src/protobuf/model/code.rs @@ -55,6 +55,8 @@ pub enum ErrorCode { UserNameIsEmpty = 310, UserIdInvalid = 311, UserNotExist = 312, + TextTooLong = 400, + InvalidData = 401, } impl ::protobuf::ProtobufEnum for ErrorCode { @@ -94,6 +96,8 @@ impl ::protobuf::ProtobufEnum for ErrorCode { 310 => ::std::option::Option::Some(ErrorCode::UserNameIsEmpty), 311 => ::std::option::Option::Some(ErrorCode::UserIdInvalid), 312 => ::std::option::Option::Some(ErrorCode::UserNotExist), + 400 => ::std::option::Option::Some(ErrorCode::TextTooLong), + 401 => ::std::option::Option::Some(ErrorCode::InvalidData), _ => ::std::option::Option::None } } @@ -130,6 +134,8 @@ impl ::protobuf::ProtobufEnum for ErrorCode { ErrorCode::UserNameIsEmpty, ErrorCode::UserIdInvalid, ErrorCode::UserNotExist, + ErrorCode::TextTooLong, + ErrorCode::InvalidData, ]; values } @@ -158,7 +164,7 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ncode.proto*\xc4\x05\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ + \n\ncode.proto*\xe8\x05\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ \n\x10UserUnauthorized\x10\x02\x12\x12\n\x0eRecordNotFound\x10\x03\x12\ \x18\n\x14WorkspaceNameInvalid\x10d\x12\x16\n\x12WorkspaceIdInvalid\x10e\ \x12\x18\n\x14AppColorStyleInvalid\x10f\x12\x18\n\x14WorkspaceDescTooLon\ @@ -174,8 +180,9 @@ static file_descriptor_proto_data: &'static [u8] = b"\ rmatInvalid\x10\xb2\x02\x12\x15\n\x10PasswordNotMatch\x10\xb3\x02\x12\ \x14\n\x0fUserNameTooLong\x10\xb4\x02\x12'\n\"UserNameContainForbiddenCh\ aracters\x10\xb5\x02\x12\x14\n\x0fUserNameIsEmpty\x10\xb6\x02\x12\x12\n\ - \rUserIdInvalid\x10\xb7\x02\x12\x11\n\x0cUserNotExist\x10\xb8\x02b\x06pr\ - oto3\ + \rUserIdInvalid\x10\xb7\x02\x12\x11\n\x0cUserNotExist\x10\xb8\x02\x12\ + \x10\n\x0bTextTooLong\x10\x90\x03\x12\x10\n\x0bInvalidData\x10\x91\x03b\ + \x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto index ed12d58848..4bf692b8ff 100644 --- a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto +++ b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto @@ -31,4 +31,6 @@ enum ErrorCode { UserNameIsEmpty = 310; UserIdInvalid = 311; UserNotExist = 312; + TextTooLong = 400; + InvalidData = 401; } diff --git a/shared-lib/flowy-folder-data-model/src/entities/view.rs b/shared-lib/flowy-folder-data-model/src/entities/view.rs index ac346188ce..3b98e3f64c 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/view.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/view.rs @@ -4,7 +4,7 @@ use crate::{ impl_def_and_def_mut, parser::{ app::AppIdentify, - view::{ViewDesc, ViewExtensionData, ViewIdentify, ViewName, ViewThumbnail}, + view::{ViewDesc, ViewIdentify, ViewName, ViewThumbnail}, }, }; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index f8c762345d..d70d17e0e9 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -1,7 +1,7 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; -use strum::{EnumCount, IntoEnumIterator}; + use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 36; @@ -35,6 +35,10 @@ impl GridBlock { pub fn len(&self) -> i32 { self.start_row_index + self.row_count } + + pub fn is_empty(&self) -> bool { + self.row_count == 0 + } } impl GridBlock { diff --git a/shared-lib/lib-infra/src/future.rs b/shared-lib/lib-infra/src/future.rs index 9a0b6550dd..9077dd18b7 100644 --- a/shared-lib/lib-infra/src/future.rs +++ b/shared-lib/lib-infra/src/future.rs @@ -65,34 +65,3 @@ where } pub type BoxResultFuture<'a, T, E> = BoxFuture<'a, Result>; - -#[pin_project] -pub struct FutureResultSend { - #[pin] - pub fut: Pin> + Send>>, -} - -impl FutureResultSend { - pub fn new(f: F) -> Self - where - F: Future> + Send + 'static, - { - Self { - fut: Box::pin(async { f.await }), - } - } -} - -impl Future for FutureResultSend -where - T: Send, - E: Debug, -{ - type Output = Result; - - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let this = self.as_mut().project(); - let result = ready!(this.fut.poll(cx)); - Poll::Ready(result) - } -} From 8c148e3b67bdeea448dc0b7c5068e2609bd9092d Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 16 Mar 2022 16:10:35 +0800 Subject: [PATCH 23/28] chore: save text cell data & insert row --- .../lib/startup/home_deps_resolver.dart | 43 ++- .../grid/cell_bloc/cell_service.dart | 30 ++- .../grid/cell_bloc/checkbox_cell_bloc.dart | 6 +- .../grid/cell_bloc/date_cell_bloc.dart | 6 +- .../grid/cell_bloc/number_cell_bloc.dart | 6 +- .../grid/cell_bloc/selection_cell_bloc.dart | 6 +- .../grid/cell_bloc/text_cell_bloc.dart | 11 +- .../lib/workspace/application/grid/data.dart | 5 + .../workspace/application/grid/grid_bloc.dart | 7 +- .../application/grid/grid_listener.dart | 0 .../application/grid/grid_service.dart | 6 +- .../workspace/application/grid/row_bloc.dart | 6 +- .../application/grid/row_service.dart | 13 +- .../src/widgets/content/cell_builder.dart | 18 +- .../src/widgets/content/checkbox_cell.dart | 12 +- .../grid/src/widgets/content/date_cell.dart | 12 +- .../grid/src/widgets/content/grid_row.dart | 19 +- .../grid/src/widgets/content/number_cell.dart | 10 +- .../src/widgets/content/selection_cell.dart | 21 +- .../grid/src/widgets/content/text_cell.dart | 13 +- .../grid/src/widgets/footer/grid_footer.dart | 10 +- .../dart_event/flowy-grid/dart_event.dart | 8 +- .../flowy-error-code/code.pbenum.dart | 4 + .../flowy-error-code/code.pbjson.dart | 4 +- .../flowy-grid-data-model/grid.pb.dart | 74 +++++ .../flowy-grid-data-model/grid.pbjson.dart | 14 + .../flowy-grid-data-model/meta.pb.dart | 48 ++-- .../flowy-grid-data-model/meta.pbjson.dart | 9 +- .../rust-lib/flowy-grid/src/event_handler.rs | 25 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 4 +- .../src/services/block_meta_editor.rs | 10 +- .../flowy-grid/src/services/grid_editor.rs | 25 +- .../src/services/row/row_builder.rs | 14 +- .../flowy-grid/src/services/row/row_loader.rs | 1 + frontend/rust-lib/flowy-grid/src/util.rs | 3 +- .../flowy-grid/tests/grid/grid_test.rs | 21 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 4 +- .../src/client_grid/block_pad.rs | 96 ++++++- .../src/entities/grid.rs | 9 + .../src/entities/meta.rs | 7 +- .../src/protobuf/model/grid.rs | 254 +++++++++++++++++- .../src/protobuf/model/meta.rs | 85 ++++-- .../src/protobuf/proto/grid.proto | 4 + .../src/protobuf/proto/meta.proto | 7 +- 44 files changed, 759 insertions(+), 231 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 5b91d8a545..cbb359f09d 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -98,8 +98,7 @@ class HomeDepsResolver { getIt.registerFactoryParam( (data, _) => RowBloc( - data: data, - service: RowService(), + service: RowService(data), ), ); @@ -110,43 +109,33 @@ class HomeDepsResolver { ), ); - getIt.registerFactoryParam( - (field, cell) => TextCellBloc( - field: field, - cell: cell, - service: CellService(), + getIt.registerFactoryParam( + (context, _) => TextCellBloc( + service: CellService(context), ), ); - getIt.registerFactoryParam( - (field, cell) => SelectionCellBloc( - field: field, - cell: cell, - service: CellService(), + getIt.registerFactoryParam( + (context, _) => SelectionCellBloc( + service: CellService(context), ), ); - getIt.registerFactoryParam( - (field, cell) => NumberCellBloc( - field: field, - cell: cell, - service: CellService(), + getIt.registerFactoryParam( + (context, _) => NumberCellBloc( + service: CellService(context), ), ); - getIt.registerFactoryParam( - (field, cell) => DateCellBloc( - field: field, - cell: cell, - service: CellService(), + getIt.registerFactoryParam( + (context, _) => DateCellBloc( + service: CellService(context), ), ); - getIt.registerFactoryParam( - (field, cell) => CheckboxCellBloc( - field: field, - cell: cell, - service: CellService(), + getIt.registerFactoryParam( + (context, _) => CheckboxCellBloc( + service: CellService(context), ), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart index c5098155cb..456615220d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -1 +1,29 @@ -class CellService {} +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; + +class CellService { + final CellContext context; + + CellService(this.context); + + Future> updateCell({required String data}) { + final payload = CellMetaChangeset.create() + ..gridId = context.gridId + ..fieldId = context.field.id + ..rowId = context.rowId + ..data = data; + return GridEventUpdateCell(payload).send(); + } +} + +class CellContext { + final String gridId; + final String rowId; + final Field field; + final Cell? cell; + + CellContext({required this.rowId, required this.gridId, required this.field, required this.cell}); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index 8f0de7fb32..ab844448dc 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -7,15 +7,11 @@ import 'cell_service.dart'; part 'checkbox_cell_bloc.freezed.dart'; class CheckboxCellBloc extends Bloc { - final Field field; - final Cell? cell; final CellService service; CheckboxCellBloc({ - required this.field, - required this.cell, required this.service, - }) : super(CheckboxCellState.initial(cell)) { + }) : super(CheckboxCellState.initial(service.context.cell)) { on( (event, emit) async { await event.map( diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart index c8b5e97f2d..dcb0461165 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/date_cell_bloc.dart @@ -7,15 +7,11 @@ import 'cell_service.dart'; part 'date_cell_bloc.freezed.dart'; class DateCellBloc extends Bloc { - final Field field; - final Cell? cell; final CellService service; DateCellBloc({ - required this.field, - required this.cell, required this.service, - }) : super(DateCellState.initial(cell)) { + }) : super(DateCellState.initial(service.context.cell)) { on( (event, emit) async { await event.map( diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart index b216550a81..caa91fa408 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/number_cell_bloc.dart @@ -7,15 +7,11 @@ import 'cell_service.dart'; part 'number_cell_bloc.freezed.dart'; class NumberCellBloc extends Bloc { - final Field field; - final Cell? cell; final CellService service; NumberCellBloc({ - required this.field, - required this.cell, required this.service, - }) : super(NumberCellState.initial(cell)) { + }) : super(NumberCellState.initial(service.context.cell)) { on( (event, emit) async { await event.map( diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index 5e7a6e8e22..7f21a84fff 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -7,15 +7,11 @@ import 'cell_service.dart'; part 'selection_cell_bloc.freezed.dart'; class SelectionCellBloc extends Bloc { - final Field field; - final Cell? cell; final CellService service; SelectionCellBloc({ - required this.field, - required this.cell, required this.service, - }) : super(SelectionCellState.initial(cell)) { + }) : super(SelectionCellState.initial(service.context.cell)) { on( (event, emit) async { await event.map( diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart index cce4ff9224..80bc722be7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/text_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'; @@ -7,20 +6,18 @@ import 'cell_service.dart'; part 'text_cell_bloc.freezed.dart'; class TextCellBloc extends Bloc { - final Field field; - final Cell? cell; final CellService service; TextCellBloc({ - required this.field, - required this.cell, required this.service, - }) : super(TextCellState.initial(cell?.content ?? "")) { + }) : super(TextCellState.initial(service.context.cell?.content ?? "")) { on( (event, emit) async { await event.map( initial: (_InitialCell value) async {}, - updateText: (_UpdateText value) {}, + updateText: (_UpdateText value) { + service.updateCell(data: value.text); + }, ); }, ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart index c32f87f1a2..77cb1d9e6d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -2,10 +2,12 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:equatable/equatable.dart'; class GridInfo { + final String gridId; List rows; List fields; GridInfo({ + required this.gridId, required this.rows, required this.fields, }); @@ -13,6 +15,7 @@ class GridInfo { GridRowData rowAtIndex(int index) { final row = rows[index]; return GridRowData( + gridId: gridId, row: row, fields: fields, cellMap: row.cellByFieldId, @@ -25,10 +28,12 @@ class GridInfo { } class GridRowData extends Equatable { + final String gridId; final Row row; final List fields; final Map cellMap; const GridRowData({ + required this.gridId, required this.row, required this.fields, required this.cellMap, diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart index 500db75bf3..b67f119fe3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -70,11 +70,12 @@ class GridBloc extends Bloc { } Future _loadGridInfo(Emitter emit) async { - if (_grid != null && _fields != null) { - final result = await service.getRows(gridId: _grid!.id, rowOrders: _grid!.rowOrders); + final grid = _grid; + if (grid != null && _fields != null) { + final result = await service.getRows(gridId: grid.id, rowOrders: grid.rowOrders); result.fold((repeatedRow) { final rows = repeatedRow.items; - final gridInfo = GridInfo(rows: rows, fields: _fields!); + final gridInfo = GridInfo(gridId: grid.id, rows: rows, fields: _fields!); emit( state.copyWith(loadingState: GridLoadingState.finish(left(unit)), gridInfo: some(left(gridInfo))), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index e519b0a90d..915cc671b6 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -12,8 +12,10 @@ class GridService { return GridEventGetGridData(payload).send(); } - Future> createRow({required String gridId}) { - return GridEventCreateRow(GridId(value: gridId)).send(); + Future> createRow({required String gridId, Option? upperRowId}) { + CreateRowPayload payload = CreateRowPayload.create()..gridId = gridId; + upperRowId?.fold(() => null, (id) => payload.upperRowId = id); + return GridEventCreateRow(payload).send(); } Future> getRows({required String gridId, required List rowOrders}) { diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart index d2852900d9..1dd20aad9a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart @@ -9,12 +9,14 @@ part 'row_bloc.freezed.dart'; class RowBloc extends Bloc { final RowService service; - RowBloc({required GridRowData data, required this.service}) : super(RowState.initial(data)) { + RowBloc({required this.service}) : super(RowState.initial(service.rowData)) { on( (event, emit) async { await event.map( initial: (_InitialRow value) async {}, - createRow: (_CreateRow value) {}, + createRow: (_CreateRow value) { + service.createRow(); + }, activeRow: (_ActiveRow value) { emit(state.copyWith(active: true)); }, diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart index ad04b0add2..03d732f862 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart @@ -1,10 +1,19 @@ +import 'package:app_flowy/workspace/application/grid/data.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; class RowService { - Future> createRow({required String gridId}) { - return GridEventCreateRow(GridId(value: gridId)).send(); + final GridRowData rowData; + + RowService(this.rowData); + + Future> createRow() { + CreateRowPayload payload = CreateRowPayload.create() + ..gridId = rowData.gridId + ..upperRowId = rowData.row.id; + + return GridEventCreateRow(payload).send(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index 0abfc26047..7b183abbe5 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -1,4 +1,4 @@ -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'checkbox_cell.dart'; @@ -7,20 +7,20 @@ import 'number_cell.dart'; import 'selection_cell.dart'; import 'text_cell.dart'; -Widget buildGridCell(Field field, Cell? cell) { - switch (field.fieldType) { +Widget buildGridCell(CellContext cellContext) { + switch (cellContext.field.fieldType) { case FieldType.Checkbox: - return CheckboxCell(field: field, cell: cell); + return CheckboxCell(cellContext: cellContext); case FieldType.DateTime: - return DateCell(field: field, cell: cell); + return DateCell(cellContext: cellContext); case FieldType.MultiSelect: - return MultiSelectCell(field: field, cell: cell); + return MultiSelectCell(cellContext: cellContext); case FieldType.Number: - return NumberCell(field: field, cell: cell); + return NumberCell(cellContext: cellContext); case FieldType.RichText: - return GridTextCell(field: field, cell: cell); + return GridTextCell(cellContext: cellContext); case FieldType.SingleSelect: - return SingleSelectCell(field: field, cell: cell); + return SingleSelectCell(cellContext: cellContext); default: return const BlankCell(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart index d3d2b57735..ec3e51b102 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart @@ -1,16 +1,14 @@ import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class CheckboxCell extends StatefulWidget { - final Field field; - final Cell? cell; + final CellContext cellContext; const CheckboxCell({ - required this.field, - required this.cell, + required this.cellContext, Key? key, }) : super(key: key); @@ -23,7 +21,7 @@ class _CheckboxCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.field, param2: widget.cell); + _cellBloc = getIt(param1: widget.cellContext); super.initState(); } @@ -41,7 +39,7 @@ class _CheckboxCellState extends State { @override Future dispose() async { - await _cellBloc.close(); + _cellBloc.close(); super.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart index e1661fdffa..dbe631f2f1 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart @@ -1,16 +1,14 @@ import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/date_cell_bloc.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class DateCell extends StatefulWidget { - final Field field; - final Cell? cell; + final CellContext cellContext; const DateCell({ - required this.field, - required this.cell, + required this.cellContext, Key? key, }) : super(key: key); @@ -23,7 +21,7 @@ class _DateCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.field, param2: widget.cell); + _cellBloc = getIt(param1: widget.cellContext); super.initState(); } @@ -41,7 +39,7 @@ class _DateCellState extends State { @override Future dispose() async { - await _cellBloc.close(); + _cellBloc.close(); super.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index c23bf8f533..c8bd05c3fe 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -54,7 +54,7 @@ class _GridRowWidgetState extends State { @override Future dispose() async { - await _rowBloc.close(); + _rowBloc.close(); super.dispose(); } @@ -66,10 +66,17 @@ class _GridRowWidgetState extends State { key: ValueKey(state.data.row.id), children: state.data.fields.map( (field) { - final cellData = state.data.cellMap[field.id]; + final cell = state.data.cellMap[field.id]; return CellContainer( width: field.width.toDouble(), - child: buildGridCell(field, cellData), + child: buildGridCell( + CellContext( + gridId: state.data.gridId, + rowId: state.data.row.id, + field: field, + cell: cell, + ), + ), ); }, ).toList(), @@ -93,7 +100,7 @@ class LeadingRow extends StatelessWidget { ? Row( mainAxisAlignment: MainAxisAlignment.center, children: const [ - CreateRowButton(), + AppendRowButton(), ], ) : null, @@ -125,8 +132,8 @@ class TrailingRow extends StatelessWidget { } } -class CreateRowButton extends StatelessWidget { - const CreateRowButton({Key? key}) : super(key: key); +class AppendRowButton extends StatelessWidget { + const AppendRowButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart index 86b9863019..c624618ec7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart @@ -1,16 +1,14 @@ import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/number_cell_bloc.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class NumberCell extends StatefulWidget { - final Field field; - final Cell? cell; + final CellContext cellContext; const NumberCell({ - required this.field, - required this.cell, + required this.cellContext, Key? key, }) : super(key: key); @@ -23,7 +21,7 @@ class _NumberCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.field, param2: widget.cell); + _cellBloc = getIt(param1: widget.cellContext); super.initState(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart index 047cff7475..575815013d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart @@ -1,15 +1,12 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; class SingleSelectCell extends StatefulWidget { - final Field field; - final Cell? cell; + final CellContext cellContext; const SingleSelectCell({ - required this.field, - required this.cell, + required this.cellContext, Key? key, }) : super(key: key); @@ -22,7 +19,7 @@ class _SingleSelectCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.field, param2: widget.cell); + _cellBloc = getIt(param1: widget.cellContext); super.initState(); } @@ -33,19 +30,17 @@ class _SingleSelectCellState extends State { @override Future dispose() async { - await _cellBloc.close(); + _cellBloc.close(); super.dispose(); } } //---------------------------------------------------------------- class MultiSelectCell extends StatefulWidget { - final Field field; - final Cell? cell; + final CellContext cellContext; const MultiSelectCell({ - required this.field, - required this.cell, + required this.cellContext, Key? key, }) : super(key: key); @@ -58,7 +53,7 @@ class _MultiSelectCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.field, param2: widget.cell); + _cellBloc = getIt(param1: widget.cellContext); super.initState(); } @@ -69,7 +64,7 @@ class _MultiSelectCellState extends State { @override Future dispose() async { - await _cellBloc.close(); + _cellBloc.close(); super.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart index 7661ddc22f..c5c330616b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -1,18 +1,15 @@ import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; /// The interface of base cell. class GridTextCell extends StatefulWidget { - final Field field; - final Cell? cell; - + final CellContext cellContext; const GridTextCell({ - required this.field, - required this.cell, + required this.cellContext, Key? key, }) : super(key: key); @@ -27,7 +24,7 @@ class _GridTextCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.field, param2: widget.cell); + _cellBloc = getIt(param1: widget.cellContext); _controller = TextEditingController(text: _cellBloc.state.content); _focusNode.addListener(_focusChanged); super.initState(); @@ -58,7 +55,7 @@ class _GridTextCellState extends State { @override Future dispose() async { - await _cellBloc.close(); + _cellBloc.close(); _focusNode.removeListener(_focusChanged); _focusNode.dispose(); super.dispose(); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart index 5ca3bf0f6b..69e27a0fc4 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/application/grid/row_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; @@ -20,7 +20,7 @@ class GridFooter extends StatelessWidget { child: Row( children: [ SizedBox(width: GridSize.leadingHeaderPadding), - const SizedBox(width: 120, child: AddRowButton()), + const SizedBox(width: 120, child: _AddRowButton()), ], ), ), @@ -29,8 +29,8 @@ class GridFooter extends StatelessWidget { } } -class AddRowButton extends StatelessWidget { - const AddRowButton({Key? key}) : super(key: key); +class _AddRowButton extends StatelessWidget { + const _AddRowButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -38,7 +38,7 @@ class AddRowButton extends StatelessWidget { return FlowyButton( text: const FlowyText.medium('New row', fontSize: 12), hoverColor: theme.hover, - onTap: () => context.read().add(const RowEvent.createRow()), + onTap: () => context.read().add(const GridEvent.createRow()), icon: svg("home/add"), ); } 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 4aeda8ede9..19c46c8306 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 @@ -53,24 +53,24 @@ class GridEventGetFields { } class GridEventCreateRow { - GridId request; + CreateRowPayload request; GridEventCreateRow(this.request); - Future> send() { + Future> send() { final request = FFIRequest.create() ..event = GridEvent.CreateRow.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) .then((bytesResult) => bytesResult.fold( - (bytes) => left(unit), + (okBytes) => left(Row.fromBuffer(okBytes)), (errBytes) => right(FlowyError.fromBuffer(errBytes)), )); } } class GridEventUpdateCell { - Cell request; + CellMetaChangeset request; GridEventUpdateCell(this.request); Future> send() { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart index dcf1e69936..69efeb81b7 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart @@ -40,6 +40,8 @@ class ErrorCode extends $pb.ProtobufEnum { static const ErrorCode UserNameIsEmpty = ErrorCode._(310, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameIsEmpty'); static const ErrorCode UserIdInvalid = ErrorCode._(311, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdInvalid'); static const ErrorCode UserNotExist = ErrorCode._(312, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotExist'); + static const ErrorCode TextTooLong = ErrorCode._(400, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TextTooLong'); + static const ErrorCode InvalidData = ErrorCode._(401, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidData'); static const $core.List values = [ Internal, @@ -72,6 +74,8 @@ class ErrorCode extends $pb.ProtobufEnum { UserNameIsEmpty, UserIdInvalid, UserNotExist, + TextTooLong, + InvalidData, ]; static final $core.Map<$core.int, ErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart index c8d7191d54..26a0b31029 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart @@ -42,8 +42,10 @@ const ErrorCode$json = const { const {'1': 'UserNameIsEmpty', '2': 310}, const {'1': 'UserIdInvalid', '2': 311}, const {'1': 'UserNotExist', '2': 312}, + const {'1': 'TextTooLong', '2': 400}, + const {'1': 'InvalidData', '2': 401}, ], }; /// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIYChRXb3Jrc3BhY2VOYW1lSW52YWxpZBBkEhYKEldvcmtzcGFjZUlkSW52YWxpZBBlEhgKFEFwcENvbG9yU3R5bGVJbnZhbGlkEGYSGAoUV29ya3NwYWNlRGVzY1Rvb0xvbmcQZxIYChRXb3Jrc3BhY2VOYW1lVG9vTG9uZxBoEhAKDEFwcElkSW52YWxpZBBuEhIKDkFwcE5hbWVJbnZhbGlkEG8SEwoPVmlld05hbWVJbnZhbGlkEHgSGAoUVmlld1RodW1ibmFpbEludmFsaWQQeRIRCg1WaWV3SWRJbnZhbGlkEHoSEwoPVmlld0Rlc2NUb29Mb25nEHsSEwoPVmlld0RhdGFJbnZhbGlkEHwSEwoPVmlld05hbWVUb29Mb25nEH0SEQoMQ29ubmVjdEVycm9yEMgBEhEKDEVtYWlsSXNFbXB0eRCsAhIXChJFbWFpbEZvcm1hdEludmFsaWQQrQISFwoSRW1haWxBbHJlYWR5RXhpc3RzEK4CEhQKD1Bhc3N3b3JkSXNFbXB0eRCvAhIUCg9QYXNzd29yZFRvb0xvbmcQsAISJQogUGFzc3dvcmRDb250YWluc0ZvcmJpZENoYXJhY3RlcnMQsQISGgoVUGFzc3dvcmRGb3JtYXRJbnZhbGlkELICEhUKEFBhc3N3b3JkTm90TWF0Y2gQswISFAoPVXNlck5hbWVUb29Mb25nELQCEicKIlVzZXJOYW1lQ29udGFpbkZvcmJpZGRlbkNoYXJhY3RlcnMQtQISFAoPVXNlck5hbWVJc0VtcHR5ELYCEhIKDVVzZXJJZEludmFsaWQQtwISEQoMVXNlck5vdEV4aXN0ELgC'); +final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIYChRXb3Jrc3BhY2VOYW1lSW52YWxpZBBkEhYKEldvcmtzcGFjZUlkSW52YWxpZBBlEhgKFEFwcENvbG9yU3R5bGVJbnZhbGlkEGYSGAoUV29ya3NwYWNlRGVzY1Rvb0xvbmcQZxIYChRXb3Jrc3BhY2VOYW1lVG9vTG9uZxBoEhAKDEFwcElkSW52YWxpZBBuEhIKDkFwcE5hbWVJbnZhbGlkEG8SEwoPVmlld05hbWVJbnZhbGlkEHgSGAoUVmlld1RodW1ibmFpbEludmFsaWQQeRIRCg1WaWV3SWRJbnZhbGlkEHoSEwoPVmlld0Rlc2NUb29Mb25nEHsSEwoPVmlld0RhdGFJbnZhbGlkEHwSEwoPVmlld05hbWVUb29Mb25nEH0SEQoMQ29ubmVjdEVycm9yEMgBEhEKDEVtYWlsSXNFbXB0eRCsAhIXChJFbWFpbEZvcm1hdEludmFsaWQQrQISFwoSRW1haWxBbHJlYWR5RXhpc3RzEK4CEhQKD1Bhc3N3b3JkSXNFbXB0eRCvAhIUCg9QYXNzd29yZFRvb0xvbmcQsAISJQogUGFzc3dvcmRDb250YWluc0ZvcmJpZENoYXJhY3RlcnMQsQISGgoVUGFzc3dvcmRGb3JtYXRJbnZhbGlkELICEhUKEFBhc3N3b3JkTm90TWF0Y2gQswISFAoPVXNlck5hbWVUb29Mb25nELQCEicKIlVzZXJOYW1lQ29udGFpbkZvcmJpZGRlbkNoYXJhY3RlcnMQtQISFAoPVXNlck5hbWVJc0VtcHR5ELYCEhIKDVVzZXJJZEludmFsaWQQtwISEQoMVXNlck5vdEV4aXN0ELgCEhAKC1RleHRUb29Mb25nEJADEhAKC0ludmFsaWREYXRhEJED'); 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 60a0502420..f89285ba92 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 @@ -701,6 +701,80 @@ class GridId extends $pb.GeneratedMessage { void clearValue() => clearField(1); } +enum CreateRowPayload_OneOfUpperRowId { + upperRowId, + notSet +} + +class CreateRowPayload extends $pb.GeneratedMessage { + static const $core.Map<$core.int, CreateRowPayload_OneOfUpperRowId> _CreateRowPayload_OneOfUpperRowIdByTag = { + 2 : CreateRowPayload_OneOfUpperRowId.upperRowId, + 0 : CreateRowPayload_OneOfUpperRowId.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateRowPayload', createEmptyInstance: create) + ..oo(0, [2]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'upperRowId') + ..hasRequiredFields = false + ; + + CreateRowPayload._() : super(); + factory CreateRowPayload({ + $core.String? gridId, + $core.String? upperRowId, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (upperRowId != null) { + _result.upperRowId = upperRowId; + } + return _result; + } + factory CreateRowPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CreateRowPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CreateRowPayload clone() => CreateRowPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CreateRowPayload copyWith(void Function(CreateRowPayload) updates) => super.copyWith((message) => updates(message as CreateRowPayload)) as CreateRowPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CreateRowPayload create() => CreateRowPayload._(); + CreateRowPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CreateRowPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CreateRowPayload? _defaultInstance; + + CreateRowPayload_OneOfUpperRowId whichOneOfUpperRowId() => _CreateRowPayload_OneOfUpperRowIdByTag[$_whichOneof(0)]!; + void clearOneOfUpperRowId() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + $core.String get gridId => $_getSZ(0); + @$pb.TagNumber(1) + set gridId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasGridId() => $_has(0); + @$pb.TagNumber(1) + void clearGridId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get upperRowId => $_getSZ(1); + @$pb.TagNumber(2) + set upperRowId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasUpperRowId() => $_has(1); + @$pb.TagNumber(2) + void clearUpperRowId() => clearField(2); +} + class QueryFieldPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryFieldPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') 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 0dc1fd25f6..1504b31506 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 @@ -151,6 +151,20 @@ const GridId$json = const { /// Descriptor for `GridId`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridIdDescriptor = $convert.base64Decode('CgZHcmlkSWQSFAoFdmFsdWUYASABKAlSBXZhbHVl'); +@$core.Deprecated('Use createRowPayloadDescriptor instead') +const CreateRowPayload$json = const { + '1': 'CreateRowPayload', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'upper_row_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'upperRowId'}, + ], + '8': const [ + const {'1': 'one_of_upper_row_id'}, + ], +}; + +/// Descriptor for `CreateRowPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List createRowPayloadDescriptor = $convert.base64Decode('ChBDcmVhdGVSb3dQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIiCgx1cHBlcl9yb3dfaWQYAiABKAlIAFIKdXBwZXJSb3dJZEIVChNvbmVfb2ZfdXBwZXJfcm93X2lk'); @$core.Deprecated('Use queryFieldPayloadDescriptor instead') const QueryFieldPayload$json = const { '1': 'QueryFieldPayload', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 0a0837d2df..38adc076a6 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -922,24 +922,29 @@ enum CellMetaChangeset_OneOfData { class CellMetaChangeset extends $pb.GeneratedMessage { static const $core.Map<$core.int, CellMetaChangeset_OneOfData> _CellMetaChangeset_OneOfDataByTag = { - 3 : CellMetaChangeset_OneOfData.data, + 4 : CellMetaChangeset_OneOfData.data, 0 : CellMetaChangeset_OneOfData.notSet }; static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellMetaChangeset', createEmptyInstance: create) - ..oo(0, [3]) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') + ..oo(0, [4]) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') ..hasRequiredFields = false ; CellMetaChangeset._() : super(); factory CellMetaChangeset({ + $core.String? gridId, $core.String? rowId, $core.String? fieldId, $core.String? data, }) { final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } if (rowId != null) { _result.rowId = rowId; } @@ -976,31 +981,40 @@ class CellMetaChangeset extends $pb.GeneratedMessage { void clearOneOfData() => clearField($_whichOneof(0)); @$pb.TagNumber(1) - $core.String get rowId => $_getSZ(0); + $core.String get gridId => $_getSZ(0); @$pb.TagNumber(1) - set rowId($core.String v) { $_setString(0, v); } + set gridId($core.String v) { $_setString(0, v); } @$pb.TagNumber(1) - $core.bool hasRowId() => $_has(0); + $core.bool hasGridId() => $_has(0); @$pb.TagNumber(1) - void clearRowId() => clearField(1); + void clearGridId() => clearField(1); @$pb.TagNumber(2) - $core.String get fieldId => $_getSZ(1); + $core.String get rowId => $_getSZ(1); @$pb.TagNumber(2) - set fieldId($core.String v) { $_setString(1, v); } + set rowId($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasFieldId() => $_has(1); + $core.bool hasRowId() => $_has(1); @$pb.TagNumber(2) - void clearFieldId() => clearField(2); + void clearRowId() => clearField(2); @$pb.TagNumber(3) - $core.String get data => $_getSZ(2); + $core.String get fieldId => $_getSZ(2); @$pb.TagNumber(3) - set data($core.String v) { $_setString(2, v); } + set fieldId($core.String v) { $_setString(2, v); } @$pb.TagNumber(3) - $core.bool hasData() => $_has(2); + $core.bool hasFieldId() => $_has(2); @$pb.TagNumber(3) - void clearData() => clearField(3); + void clearFieldId() => clearField(3); + + @$pb.TagNumber(4) + $core.String get data => $_getSZ(3); + @$pb.TagNumber(4) + set data($core.String v) { $_setString(3, v); } + @$pb.TagNumber(4) + $core.bool hasData() => $_has(3); + @$pb.TagNumber(4) + void clearData() => clearField(4); } class BuildGridContext extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 4dceb2116b..7ce08c0a9d 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -180,9 +180,10 @@ final $typed_data.Uint8List cellMetaDescriptor = $convert.base64Decode('CghDZWxs const CellMetaChangeset$json = const { '1': 'CellMetaChangeset', '2': const [ - const {'1': 'row_id', '3': 1, '4': 1, '5': 9, '10': 'rowId'}, - const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'data', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'data'}, + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, + const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'data', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'data'}, ], '8': const [ const {'1': 'one_of_data'}, @@ -190,7 +191,7 @@ const CellMetaChangeset$json = const { }; /// Descriptor for `CellMetaChangeset`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellMetaChangesetDescriptor = $convert.base64Decode('ChFDZWxsTWV0YUNoYW5nZXNldBIVCgZyb3dfaWQYASABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAIgASgJUgdmaWVsZElkEhQKBGRhdGEYAyABKAlIAFIEZGF0YUINCgtvbmVfb2ZfZGF0YQ=='); +final $typed_data.Uint8List cellMetaChangesetDescriptor = $convert.base64Decode('ChFDZWxsTWV0YUNoYW5nZXNldBIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIZCghmaWVsZF9pZBgDIAEoCVIHZmllbGRJZBIUCgRkYXRhGAQgASgJSABSBGRhdGFCDQoLb25lX29mX2RhdGE='); @$core.Deprecated('Use buildGridContextDescriptor instead') const BuildGridContext$json = const { '1': 'BuildGridContext', diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 28e25854d0..e92556b554 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,7 +1,8 @@ use crate::manager::GridManager; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ - Cell, Field, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedRow, + CellMetaChangeset, CreateRowPayload, Field, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, + RepeatedRow, Row, }; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -42,22 +43,22 @@ pub(crate) async fn get_fields_handler( #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn create_row_handler( - data: Data, + data: Data, manager: AppData>, -) -> Result<(), FlowyError> { - let id: GridId = data.into_inner(); - let editor = manager.get_grid_editor(id.as_ref())?; - let _ = editor.create_row().await?; - Ok(()) +) -> DataResult { + let payload: CreateRowPayload = data.into_inner(); + let editor = manager.get_grid_editor(payload.grid_id.as_ref())?; + let row = editor.create_row(payload.upper_row_id).await?; + data_result(row) } #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn update_cell_handler( - data: Data, - _manager: AppData>, + data: Data, + manager: AppData>, ) -> Result<(), FlowyError> { - let _cell: Cell = data.into_inner(); - // let editor = manager.get_grid_editor(id.as_ref())?; - // let _ = editor.create_empty_row().await?; + let changeset: CellMetaChangeset = data.into_inner(); + let editor = manager.get_grid_editor(&changeset.grid_id)?; + let _ = editor.update_cell(changeset).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 773e632191..6adc06e709 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -29,9 +29,9 @@ pub enum GridEvent { #[event(input = "QueryFieldPayload", output = "RepeatedField")] GetFields = 2, - #[event(input = "GridId")] + #[event(input = "CreateRowPayload", output = "Row")] CreateRow = 3, - #[event(input = "Cell")] + #[event(input = "CellMetaChangeset")] UpdateCell = 4, } 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 f0d0b8e475..0da4b9e609 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 @@ -56,10 +56,10 @@ impl GridBlockMetaEditorManager { } } - pub(crate) async fn create_row(&self, row: RowMeta) -> FlowyResult { + pub(crate) async fn create_row(&self, row: RowMeta, upper_row_id: Option) -> FlowyResult { self.block_id_by_row_id.insert(row.id.clone(), row.block_id.clone()); let editor = self.get_editor(&row.block_id).await?; - editor.create_row(row).await + editor.create_row(row, upper_row_id).await } pub(crate) async fn insert_row( @@ -72,7 +72,7 @@ impl GridBlockMetaEditorManager { let mut row_count = 0; for row in rows { self.block_id_by_row_id.insert(row.id.clone(), row.block_id.clone()); - row_count = editor.create_row(row).await?; + row_count = editor.create_row(row, None).await?; } changesets.push(GridBlockChangeset::from_row_count(&block_id, row_count)); } @@ -215,11 +215,11 @@ impl ClientGridBlockMetaEditor { }) } - async fn create_row(&self, row: RowMeta) -> FlowyResult { + async fn create_row(&self, row: RowMeta, upper_row_id: Option) -> FlowyResult { let mut row_count = 0; let _ = self .modify(|pad| { - let change = pad.add_row(row)?; + let change = pad.add_row(row, upper_row_id)?; row_count = pad.number_of_rows(); Ok(change) }) 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 9436b62e6f..f6730565ed 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -12,8 +12,7 @@ use flowy_grid_data_model::entities::{ use std::collections::HashMap; use crate::services::row::{ - make_row_by_row_id, make_rows, row_meta_from_context, serialize_cell_data, CreateRowContext, - CreateRowContextBuilder, + make_row_by_row_id, make_rows, row_meta_from_context, serialize_cell_data, RowMetaContext, RowMetaContextBuilder, }; use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; @@ -82,18 +81,28 @@ impl ClientGridEditor { Ok(()) } - pub async fn create_row(&self) -> FlowyResult<()> { + pub async fn create_row(&self, upper_row_id: Option) -> FlowyResult { let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?; let block_id = self.last_block_id().await?; - let create_row_ctx = CreateRowContextBuilder::new(&field_metas).build(); - let row = row_meta_from_context(&block_id, create_row_ctx); - let row_count = self.block_meta_manager.create_row(row).await?; + + // insert empty row below the row whose id is upper_row_id + let row_meta_ctx = RowMetaContextBuilder::new(&field_metas).build(); + let row_meta = row_meta_from_context(&block_id, row_meta_ctx); + + // insert the row + let row_count = self + .block_meta_manager + .create_row(row_meta.clone(), upper_row_id) + .await?; + let row = make_rows(&field_metas, vec![row_meta.into()]).pop().unwrap(); + + // update block row count let changeset = GridBlockChangeset::from_row_count(&block_id, row_count); let _ = self.update_block(changeset).await?; - Ok(()) + Ok(row) } - pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult<()> { + pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult<()> { let block_id = self.last_block_id().await?; let mut rows_by_block_id: HashMap> = HashMap::new(); for ctx in contexts { diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index 676411e8c7..ce8ac6e53d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -3,19 +3,19 @@ use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT}; use std::collections::HashMap; -pub struct CreateRowContextBuilder<'a> { +pub struct RowMetaContextBuilder<'a> { field_meta_map: HashMap<&'a String, &'a FieldMeta>, - ctx: CreateRowContext, + ctx: RowMetaContext, } -impl<'a> CreateRowContextBuilder<'a> { +impl<'a> RowMetaContextBuilder<'a> { pub fn new(fields: &'a [FieldMeta]) -> Self { let field_meta_map = fields .iter() .map(|field| (&field.id, field)) .collect::>(); - let ctx = CreateRowContext { + let ctx = RowMetaContext { row_id: uuid::Uuid::new_v4().to_string(), cell_by_field_id: Default::default(), height: DEFAULT_ROW_HEIGHT, @@ -52,12 +52,12 @@ impl<'a> CreateRowContextBuilder<'a> { self } - pub fn build(self) -> CreateRowContext { + pub fn build(self) -> RowMetaContext { self.ctx } } -pub fn row_meta_from_context(block_id: &str, ctx: CreateRowContext) -> RowMeta { +pub fn row_meta_from_context(block_id: &str, ctx: RowMetaContext) -> RowMeta { RowMeta { id: ctx.row_id, block_id: block_id.to_owned(), @@ -67,7 +67,7 @@ pub fn row_meta_from_context(block_id: &str, ctx: CreateRowContext) -> RowMeta { } } -pub struct CreateRowContext { +pub struct RowMetaContext { pub row_id: String, pub cell_by_field_id: HashMap, pub height: i32, 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 aa114c3d07..02a6f760e0 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 @@ -2,6 +2,7 @@ use crate::services::row::deserialize_cell_data; use flowy_grid_data_model::entities::{Cell, CellMeta, FieldMeta, Row, RowMeta, RowOrder}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; +use std::ops::Deref; use std::sync::Arc; pub(crate) struct RowIdsPerBlock { diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index e7417b5ea7..82d5399f9e 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -12,10 +12,11 @@ pub fn make_default_grid() -> BuildGridContext { let single_select = SingleSelectTypeOptionsBuilder::default() .option(SelectOption::new("Done")) + .option(SelectOption::new("Unknown")) .option(SelectOption::new("Progress")); let single_select_field = FieldBuilder::new(single_select) - .name("Name") + .name("Status") .visibility(true) .field_type(FieldType::SingleSelect) .build(); 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 acb8e27c39..36c202f335 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::cell::*; -use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, CreateRowContextBuilder}; +use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, RowMetaContextBuilder}; use flowy_grid_data_model::entities::{ CellMetaChangeset, FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMetaChangeset, }; @@ -179,7 +179,7 @@ async fn grid_create_row() { #[tokio::test] async fn grid_create_row2() { let mut test = GridEditorTest::new().await; - let create_row_context = CreateRowContextBuilder::new(&test.field_metas).build(); + let create_row_context = RowMetaContextBuilder::new(&test.field_metas).build(); let scripts = vec![ AssertRowCount(3), CreateRow { @@ -193,7 +193,7 @@ async fn grid_create_row2() { #[tokio::test] async fn grid_update_row() { let mut test = GridEditorTest::new().await; - let context = CreateRowContextBuilder::new(&test.field_metas).build(); + let context = RowMetaContextBuilder::new(&test.field_metas).build(); let changeset = RowMetaChangeset { row_id: context.row_id.clone(), height: None, @@ -216,8 +216,8 @@ async fn grid_update_row() { #[tokio::test] async fn grid_delete_row() { let mut test = GridEditorTest::new().await; - let context_1 = CreateRowContextBuilder::new(&test.field_metas).build(); - let context_2 = CreateRowContextBuilder::new(&test.field_metas).build(); + let context_1 = RowMetaContextBuilder::new(&test.field_metas).build(); + let context_2 = RowMetaContextBuilder::new(&test.field_metas).build(); let row_ids = vec![context_1.row_id.clone(), context_2.row_id.clone()]; let scripts = vec![ AssertRowCount(3), @@ -242,7 +242,7 @@ async fn grid_delete_row() { #[tokio::test] async fn grid_row_add_cells_test() { let mut test = GridEditorTest::new().await; - let mut builder = CreateRowContextBuilder::new(&test.field_metas); + let mut builder = RowMetaContextBuilder::new(&test.field_metas); for field in &test.field_metas { match field.field_type { FieldType::RichText => { @@ -288,7 +288,7 @@ async fn grid_row_add_cells_test() { #[tokio::test] async fn grid_row_add_selection_cell_test() { let mut test = GridEditorTest::new().await; - let mut builder = CreateRowContextBuilder::new(&test.field_metas); + let mut builder = RowMetaContextBuilder::new(&test.field_metas); let uuid = uuid::Uuid::new_v4().to_string(); let mut single_select_field_id = "".to_string(); let mut multi_select_field_id = "".to_string(); @@ -343,7 +343,7 @@ async fn grid_row_add_selection_cell_test() { #[tokio::test] async fn grid_row_add_date_cell_test() { let mut test = GridEditorTest::new().await; - let mut builder = CreateRowContextBuilder::new(&test.field_metas); + let mut builder = RowMetaContextBuilder::new(&test.field_metas); let mut date_field = None; let timestamp = 1647390674; for field in &test.field_metas { @@ -373,8 +373,11 @@ async fn grid_cell_update() { let mut test = GridEditorTest::new().await; let field_metas = &test.field_metas; let row_metas = &test.row_metas; + let grid_blocks = &test.grid_blocks; assert_eq!(row_metas.len(), 3); + assert_eq!(grid_blocks.len(), 1); + let block_id = &grid_blocks.first().unwrap().id; let mut scripts = vec![]; for (index, row_meta) in row_metas.iter().enumerate() { for field_meta in field_metas { @@ -396,6 +399,7 @@ async fn grid_cell_update() { scripts.push(UpdateCell { changeset: CellMetaChangeset { + grid_id: block_id.to_string(), row_id: row_meta.id.clone(), field_id: field_meta.id.clone(), data: Some(data), @@ -416,6 +420,7 @@ async fn grid_cell_update() { scripts.push(UpdateCell { changeset: CellMetaChangeset { + grid_id: block_id.to_string(), row_id: row_meta.id.clone(), field_id: field_meta.id.clone(), data: Some(data), diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 2c784153be..a9bc34c18c 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -4,7 +4,7 @@ use flowy_collaboration::client_grid::GridBuilder; use flowy_grid::services::cell::*; use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; -use flowy_grid::services::row::CreateRowContext; +use flowy_grid::services::row::RowMetaContext; use flowy_grid_data_model::entities::{ BuildGridContext, CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlock, GridBlockChangeset, RowMeta, RowMetaChangeset, @@ -50,7 +50,7 @@ pub enum EditorScript { }, CreateEmptyRow, CreateRow { - context: CreateRowContext, + context: RowMetaContext, }, UpdateRow { changeset: RowMetaChangeset, diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index 840e4c28af..c1673259e9 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -36,8 +36,24 @@ impl GridBlockMetaPad { Self::from_delta(block_delta) } - pub fn add_row(&mut self, row: RowMeta) -> CollaborateResult> { + pub fn add_row( + &mut self, + row: RowMeta, + upper_row_id: Option, + ) -> CollaborateResult> { self.modify(|rows| { + if let Some(upper_row_id) = upper_row_id { + if upper_row_id.is_empty() { + rows.insert(0, Arc::new(row)); + return Ok(Some(())); + } + + if let Some(index) = rows.iter().position(|row| row.id == upper_row_id) { + rows.insert(index, Arc::new(row)); + return Ok(Some(())); + } + } + rows.push(Arc::new(row)); Ok(Some(())) }) @@ -202,13 +218,85 @@ mod tests { visibility: false, }; - let change = pad.add_row(row).unwrap().unwrap(); + let change = pad.add_row(row, None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); } + #[test] + fn block_meta_insert_row() { + let mut pad = test_pad(); + let row_1 = test_row_meta("1", &pad); + let row_2 = test_row_meta("2", &pad); + let row_3 = test_row_meta("3", &pad); + + let change = pad.add_row(row_1.clone(), None).unwrap().unwrap(); + assert_eq!( + change.delta.to_delta_str(), + r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + ); + + let change = pad.add_row(row_2.clone(), None).unwrap().unwrap(); + assert_eq!( + change.delta.to_delta_str(), + r#"[{"retain":101},{"insert":",{\"id\":\"2\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + ); + + let change = pad.add_row(row_3.clone(), Some("2".to_string())).unwrap().unwrap(); + assert_eq!( + change.delta.to_delta_str(), + r#"[{"retain":109},{"insert":"3\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false},{\"id\":\""},{"retain":72}]"# + ); + + assert_eq!(*pad.rows[0], row_1); + assert_eq!(*pad.rows[1], row_3); + assert_eq!(*pad.rows[2], row_2); + } + + fn test_row_meta(id: &str, pad: &GridBlockMetaPad) -> RowMeta { + RowMeta { + id: id.to_string(), + block_id: pad.block_id.clone(), + cell_by_field_id: Default::default(), + height: 0, + visibility: false, + } + } + + #[test] + fn block_meta_insert_row2() { + let mut pad = test_pad(); + let row_1 = test_row_meta("1", &pad); + let row_2 = test_row_meta("2", &pad); + let row_3 = test_row_meta("3", &pad); + + let _ = pad.add_row(row_1.clone(), None).unwrap().unwrap(); + let _ = pad.add_row(row_2.clone(), None).unwrap().unwrap(); + let _ = pad.add_row(row_3.clone(), Some("1".to_string())).unwrap().unwrap(); + + assert_eq!(*pad.rows[0], row_3); + assert_eq!(*pad.rows[1], row_1); + assert_eq!(*pad.rows[2], row_2); + } + + #[test] + fn block_meta_insert_row3() { + let mut pad = test_pad(); + let row_1 = test_row_meta("1", &pad); + let row_2 = test_row_meta("2", &pad); + let row_3 = test_row_meta("3", &pad); + + let _ = pad.add_row(row_1.clone(), None).unwrap().unwrap(); + let _ = pad.add_row(row_2.clone(), None).unwrap().unwrap(); + let _ = pad.add_row(row_3.clone(), Some("".to_string())).unwrap().unwrap(); + + assert_eq!(*pad.rows[0], row_3); + assert_eq!(*pad.rows[1], row_1); + assert_eq!(*pad.rows[2], row_2); + } + #[test] fn block_meta_delete_row() { let mut pad = test_pad(); @@ -221,7 +309,7 @@ mod tests { visibility: false, }; - let _ = pad.add_row(row.clone()).unwrap().unwrap(); + let _ = pad.add_row(row.clone(), None).unwrap().unwrap(); let change = pad.delete_rows(&[row.id]).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), @@ -249,7 +337,7 @@ mod tests { cell_by_field_id: Default::default(), }; - let _ = pad.add_row(row).unwrap().unwrap(); + let _ = pad.add_row(row, None).unwrap().unwrap(); let change = pad.update_row(changeset).unwrap().unwrap(); assert_eq!( 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 e708dc8ee7..441cc7d39e 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -222,6 +222,15 @@ impl AsRef for GridId { } } +#[derive(ProtoBuf, Default)] +pub struct CreateRowPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2, one_of)] + pub upper_row_id: Option, +} + #[derive(ProtoBuf, Default)] pub struct QueryFieldPayload { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index d70d17e0e9..34d323c5df 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -290,12 +290,15 @@ impl CellMeta { #[derive(Debug, Clone, Default, ProtoBuf)] pub struct CellMetaChangeset { #[pb(index = 1)] - pub row_id: String, + pub grid_id: String, #[pb(index = 2)] + pub row_id: String, + + #[pb(index = 3)] pub field_id: String, - #[pb(index = 3, one_of)] + #[pb(index = 4, one_of)] pub data: Option, } 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 4070675fd6..abe55edbad 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 @@ -2433,6 +2433,247 @@ impl ::protobuf::reflect::ProtobufValue for GridId { } } +#[derive(PartialEq,Clone,Default)] +pub struct CreateRowPayload { + // message fields + pub grid_id: ::std::string::String, + // message oneof groups + pub one_of_upper_row_id: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CreateRowPayload { + fn default() -> &'a CreateRowPayload { + ::default_instance() + } +} + +#[derive(Clone,PartialEq,Debug)] +pub enum CreateRowPayload_oneof_one_of_upper_row_id { + upper_row_id(::std::string::String), +} + +impl CreateRowPayload { + pub fn new() -> CreateRowPayload { + ::std::default::Default::default() + } + + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // string upper_row_id = 2; + + + pub fn get_upper_row_id(&self) -> &str { + match self.one_of_upper_row_id { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref v)) => v, + _ => "", + } + } + pub fn clear_upper_row_id(&mut self) { + self.one_of_upper_row_id = ::std::option::Option::None; + } + + pub fn has_upper_row_id(&self) -> bool { + match self.one_of_upper_row_id { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_upper_row_id(&mut self, v: ::std::string::String) { + self.one_of_upper_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(v)) + } + + // Mutable pointer to the field. + pub fn mut_upper_row_id(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(_)) = self.one_of_upper_row_id { + } else { + self.one_of_upper_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(::std::string::String::new())); + } + match self.one_of_upper_row_id { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_upper_row_id(&mut self) -> ::std::string::String { + if self.has_upper_row_id() { + match self.one_of_upper_row_id.take() { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(v)) => v, + _ => panic!(), + } + } else { + ::std::string::String::new() + } + } +} + +impl ::protobuf::Message for CreateRowPayload { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + self.one_of_upper_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(is.read_string()?)); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if let ::std::option::Option::Some(ref v) = self.one_of_upper_row_id { + match v { + &CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref v) => { + my_size += ::protobuf::rt::string_size(2, &v); + }, + }; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if let ::std::option::Option::Some(ref v) = self.one_of_upper_row_id { + match v { + &CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref v) => { + os.write_string(2, v)?; + }, + }; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> CreateRowPayload { + CreateRowPayload::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &CreateRowPayload| { &m.grid_id }, + |m: &mut CreateRowPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( + "upper_row_id", + CreateRowPayload::has_upper_row_id, + CreateRowPayload::get_upper_row_id, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CreateRowPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CreateRowPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CreateRowPayload::new) + } +} + +impl ::protobuf::Clear for CreateRowPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.one_of_upper_row_id = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CreateRowPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CreateRowPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct QueryFieldPayload { // message fields @@ -2890,11 +3131,14 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\ \x18\x02\x20\x01(\tR\x07content\"'\n\x11CreateGridPayload\x12\x12\n\x04n\ ame\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\ - \x01\x20\x01(\tR\x05value\"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\"\\\n\x0fQueryRowPayload\ - \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x120\n\nrow_orders\ - \x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrderR\trowOrdersb\x06proto3\ + \x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\ + \x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cupper_row_id\x18\x02\x20\x01(\ + \tH\0R\nupperRowIdB\x15\n\x13one_of_upper_row_id\"d\n\x11QueryFieldPaylo\ + ad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_or\ + ders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\\\n\ + \x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ + \x120\n\nrow_orders\x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrderR\trowOrde\ + rsb\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/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index 9a90b67f81..d56f2ee5a3 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -2793,6 +2793,7 @@ impl ::protobuf::reflect::ProtobufValue for CellMeta { #[derive(PartialEq,Clone,Default)] pub struct CellMetaChangeset { // message fields + pub grid_id: ::std::string::String, pub row_id: ::std::string::String, pub field_id: ::std::string::String, // message oneof groups @@ -2818,7 +2819,33 @@ impl CellMetaChangeset { ::std::default::Default::default() } - // string row_id = 1; + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // string row_id = 2; pub fn get_row_id(&self) -> &str { @@ -2844,7 +2871,7 @@ impl CellMetaChangeset { ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) } - // string field_id = 2; + // string field_id = 3; pub fn get_field_id(&self) -> &str { @@ -2870,7 +2897,7 @@ impl CellMetaChangeset { ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) } - // string data = 3; + // string data = 4; pub fn get_data(&self) -> &str { @@ -2930,12 +2957,15 @@ impl ::protobuf::Message for CellMetaChangeset { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; }, 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; }, 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 4 => { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } @@ -2953,16 +2983,19 @@ impl ::protobuf::Message for CellMetaChangeset { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } if !self.row_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.row_id); + my_size += ::protobuf::rt::string_size(2, &self.row_id); } if !self.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.field_id); + my_size += ::protobuf::rt::string_size(3, &self.field_id); } if let ::std::option::Option::Some(ref v) = self.one_of_data { match v { &CellMetaChangeset_oneof_one_of_data::data(ref v) => { - my_size += ::protobuf::rt::string_size(3, &v); + my_size += ::protobuf::rt::string_size(4, &v); }, }; } @@ -2972,16 +3005,19 @@ impl ::protobuf::Message for CellMetaChangeset { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } if !self.row_id.is_empty() { - os.write_string(1, &self.row_id)?; + os.write_string(2, &self.row_id)?; } if !self.field_id.is_empty() { - os.write_string(2, &self.field_id)?; + os.write_string(3, &self.field_id)?; } if let ::std::option::Option::Some(ref v) = self.one_of_data { match v { &CellMetaChangeset_oneof_one_of_data::data(ref v) => { - os.write_string(3, v)?; + os.write_string(4, v)?; }, }; } @@ -3023,6 +3059,11 @@ impl ::protobuf::Message for CellMetaChangeset { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &CellMetaChangeset| { &m.grid_id }, + |m: &mut CellMetaChangeset| { &mut m.grid_id }, + )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "row_id", |m: &CellMetaChangeset| { &m.row_id }, @@ -3054,6 +3095,7 @@ impl ::protobuf::Message for CellMetaChangeset { impl ::protobuf::Clear for CellMetaChangeset { fn clear(&mut self) { + self.grid_id.clear(); self.row_id.clear(); self.field_id.clear(); self.one_of_data = ::std::option::Option::None; @@ -3455,16 +3497,17 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\ \x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"9\n\x08Cell\ Meta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x12\n\x04d\ - ata\x18\x02\x20\x01(\tR\x04data\"j\n\x11CellMetaChangeset\x12\x15\n\x06r\ - ow_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x02\x20\x01\ - (\tR\x07fieldId\x12\x14\n\x04data\x18\x03\x20\x01(\tH\0R\x04dataB\r\n\ - \x0bone_of_data\"\xa2\x01\n\x10BuildGridContext\x12+\n\x0bfield_metas\ - \x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12)\n\ngrid_block\x18\ - \x02\x20\x01(\x0b2\n.GridBlockR\tgridBlock\x126\n\x0fgrid_block_meta\x18\ - \x03\x20\x01(\x0b2\x0e.GridBlockMetaR\rgridBlockMeta*d\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\x08Checkbox\x10\x05b\x06proto3\ + ata\x18\x02\x20\x01(\tR\x04data\"\x83\x01\n\x11CellMetaChangeset\x12\x17\ + \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\ + \x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07field\ + Id\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data\ + \"\xa2\x01\n\x10BuildGridContext\x12+\n\x0bfield_metas\x18\x01\x20\x03(\ + \x0b2\n.FieldMetaR\nfieldMetas\x12)\n\ngrid_block\x18\x02\x20\x01(\x0b2\ + \n.GridBlockR\tgridBlock\x126\n\x0fgrid_block_meta\x18\x03\x20\x01(\x0b2\ + \x0e.GridBlockMetaR\rgridBlockMeta*d\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\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 66dba465f6..7f01016174 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 @@ -49,6 +49,10 @@ message CreateGridPayload { message GridId { string value = 1; } +message CreateRowPayload { + string grid_id = 1; + oneof one_of_upper_row_id { string upper_row_id = 2; }; +} message QueryFieldPayload { string grid_id = 1; RepeatedFieldOrder field_orders = 2; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index 12447f6e8f..b1c8b77c40 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -56,9 +56,10 @@ message CellMeta { string data = 2; } message CellMetaChangeset { - string row_id = 1; - string field_id = 2; - oneof one_of_data { string data = 3; }; + string grid_id = 1; + string row_id = 2; + string field_id = 3; + oneof one_of_data { string data = 4; }; } message BuildGridContext { repeated FieldMeta field_metas = 1; From 1237962ab2d656653799dd39ae5f5b960b581883 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 16 Mar 2022 21:19:51 +0800 Subject: [PATCH 24/28] chore: config notification of grid --- .../lib/core/notification_helper.dart | 20 +- .../lib/startup/home_deps_resolver.dart | 7 +- .../workspace/application/grid/grid_bloc.dart | 23 ++- .../application/grid/grid_listener.dart | 60 ++++++ .../application/view/view_listener.dart | 12 +- .../plugins/grid/src/grid_page.dart | 3 +- .../flowy-grid-data-model/grid.pb.dart | 41 ++++ .../flowy-grid-data-model/grid.pbjson.dart | 10 + .../flowy-grid/dart_notification.pb.dart | 11 ++ .../flowy-grid/dart_notification.pbenum.dart | 34 ++++ .../flowy-grid/dart_notification.pbjson.dart | 25 +++ .../dart_notification.pbserver.dart | 9 + .../lib/protobuf/flowy-grid/protobuf.dart | 1 + frontend/rust-lib/flowy-grid/Flowy.toml | 2 +- .../flowy-grid/src/dart_notification.rs | 36 ++++ .../rust-lib/flowy-grid/src/event_handler.rs | 6 +- frontend/rust-lib/flowy-grid/src/lib.rs | 1 + .../src/protobuf/model/dart_notification.rs | 106 ++++++++++ .../flowy-grid/src/protobuf/model/mod.rs | 3 + .../protobuf/proto/dart_notification.proto | 10 + .../src/services/block_meta_editor.rs | 127 +++++++++--- .../flowy-grid/src/services/grid_editor.rs | 48 +++-- .../flowy-grid/src/services/row/row_loader.rs | 12 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 2 +- .../src/client_grid/grid_meta_pad.rs | 20 +- .../src/entities/grid.rs | 25 +++ .../src/protobuf/model/grid.rs | 187 +++++++++++++++++- .../src/protobuf/proto/grid.proto | 3 + 28 files changed, 763 insertions(+), 81 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbserver.dart create mode 100644 frontend/rust-lib/flowy-grid/src/dart_notification.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto diff --git a/frontend/app_flowy/lib/core/notification_helper.dart b/frontend/app_flowy/lib/core/notification_helper.dart index 88b299aa3a..d815bf92bb 100644 --- a/frontend/app_flowy/lib/core/notification_helper.dart +++ b/frontend/app_flowy/lib/core/notification_helper.dart @@ -4,7 +4,9 @@ import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; +// User typedef UserNotificationCallback = void Function(UserNotification, Either); class UserNotificationParser extends NotificationParser { @@ -17,10 +19,11 @@ class UserNotificationParser extends NotificationParser); +// Folder +typedef FolderNotificationCallback = void Function(FolderNotification, Either); class FolderNotificationParser extends NotificationParser { - FolderNotificationParser({String? id, required NotificationCallback callback}) + FolderNotificationParser({String? id, required FolderNotificationCallback callback}) : super( id: id, callback: callback, @@ -29,6 +32,19 @@ class FolderNotificationParser extends NotificationParser); + +class GridNotificationParser extends NotificationParser { + GridNotificationParser({String? id, required GridNotificationCallback callback}) + : super( + id: id, + callback: callback, + tyParser: (ty) => GridNotification.valueOf(ty), + errorParser: (bytes) => FlowyError.fromBuffer(bytes), + ); +} + class NotificationParser { String? id; void Function(T, Either) callback; diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index cbb359f09d..d66fe7cc01 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -16,6 +16,8 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:get_it/get_it.dart'; +import '../workspace/application/grid/grid_listener.dart'; + class HomeDepsResolver { static Future resolve(GetIt getIt) async { getIt.registerFactoryParam( @@ -90,10 +92,7 @@ class HomeDepsResolver { // Grid getIt.registerFactoryParam( - (view, _) => GridBloc( - view: view, - service: GridService(), - ), + (view, _) => GridBloc(view: view, service: GridService(), listener: GridListener(gridId: view.id)), ); getIt.registerFactoryParam( diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart index b67f119fe3..09e4428a83 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -1,13 +1,14 @@ import 'dart:async'; import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; - import 'data.dart'; +import 'grid_listener.dart'; import 'grid_service.dart'; part 'grid_bloc.freezed.dart'; @@ -15,14 +16,16 @@ part 'grid_bloc.freezed.dart'; class GridBloc extends Bloc { final GridService service; final View view; + final GridListener listener; Grid? _grid; List? _fields; - GridBloc({required this.view, required this.service}) : super(GridState.initial()) { + GridBloc({required this.view, required this.service, required this.listener}) : super(GridState.initial()) { on( (event, emit) async { await event.map( initial: (InitialGrid value) async { + await _startGridListening(); await _loadGrid(emit); await _loadFields(emit); await _loadGridInfo(emit); @@ -40,9 +43,25 @@ class GridBloc extends Bloc { @override Future close() async { + await listener.close(); return super.close(); } + Future _startGridListening() async { + listener.createRowNotifier.addPublishListener((result) { + result.fold((row) { + // + Log.info("$row"); + }, (err) => null); + }); + + listener.deleteRowNotifier.addPublishListener((result) { + result.fold((l) => null, (r) => null); + }); + + listener.start(); + } + Future _loadGrid(Emitter emit) async { final result = await service.openGrid(gridId: view.id); result.fold( diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart index e69de29bb2..b17544edf9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart @@ -0,0 +1,60 @@ +import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; +import 'package:flowy_sdk/rust_stream.dart'; +import 'package:flowy_infra/notifier.dart'; +import 'dart:async'; +import 'dart:typed_data'; +import 'package:app_flowy/core/notification_helper.dart'; +import 'package:dartz/dartz.dart'; + +typedef CreateRowNotifiedValue = Either; +typedef DeleteRowNotifierValue = Either; + +class GridListener { + final String gridId; + PublishNotifier createRowNotifier = PublishNotifier(); + PublishNotifier deleteRowNotifier = PublishNotifier(); + StreamSubscription? _subscription; + late GridNotificationParser _parser; + + GridListener({required this.gridId}); + + void start() { + _parser = GridNotificationParser( + id: gridId, + callback: (ty, result) { + _handleObservableType(ty, result); + }, + ); + + _subscription = RustStreamReceiver.listen((observable) => _parser.parse(observable)); + } + + void _handleObservableType(GridNotification ty, Either result) { + switch (ty) { + case GridNotification.GridDidCreateRows: + result.fold( + (payload) => createRowNotifier.value = left(RepeatedRow.fromBuffer(payload)), + (error) => createRowNotifier.value = right(error), + ); + break; + case GridNotification.GridDidDeleteRow: + result.fold( + (payload) => deleteRowNotifier.value = left(RepeatedRow.fromBuffer(payload)), + (error) => deleteRowNotifier.value = right(error), + ); + break; + + default: + break; + } + } + + Future close() async { + await _subscription?.cancel(); + createRowNotifier.dispose(); + deleteRowNotifier.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/application/view/view_listener.dart b/frontend/app_flowy/lib/workspace/application/view/view_listener.dart index c5a202e25e..f400124805 100644 --- a/frontend/app_flowy/lib/workspace/application/view/view_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/view/view_listener.dart @@ -9,15 +9,15 @@ import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart'; import 'package:flowy_sdk/rust_stream.dart'; import 'package:flowy_infra/notifier.dart'; -typedef DeleteNotifierValue = Either; -typedef UpdateNotifierValue = Either; -typedef RestoreNotifierValue = Either; +typedef DeleteViewNotifyValue = Either; +typedef UpdateViewNotifiedValue = Either; +typedef RestoreViewNotifiedValue = Either; class ViewListener { StreamSubscription? _subscription; - PublishNotifier updatedNotifier = PublishNotifier(); - PublishNotifier deletedNotifier = PublishNotifier(); - PublishNotifier restoredNotifier = PublishNotifier(); + PublishNotifier updatedNotifier = PublishNotifier(); + PublishNotifier deletedNotifier = PublishNotifier(); + PublishNotifier restoredNotifier = PublishNotifier(); late FolderNotificationParser _parser; View view; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index 7435ea0e5f..c396e7d71f 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -139,9 +139,10 @@ class _GridBodyState extends State { delegate: SliverChildBuilderDelegate( (context, index) { final data = gridInfo.rowAtIndex(index); - return RepaintBoundary(child: GridRowWidget(data: data)); + return GridRowWidget(data: data); }, childCount: gridInfo.numberOfRows(), + addRepaintBoundaries: true, ), ); } 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 f89285ba92..21f7e0f4a8 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 @@ -607,6 +607,47 @@ class Cell extends $pb.GeneratedMessage { void clearContent() => clearField(2); } +class RepeatedCell extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedCell', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Cell.create) + ..hasRequiredFields = false + ; + + RepeatedCell._() : super(); + factory RepeatedCell({ + $core.Iterable? items, + }) { + final _result = create(); + if (items != null) { + _result.items.addAll(items); + } + return _result; + } + factory RepeatedCell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedCell.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RepeatedCell clone() => RepeatedCell()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RepeatedCell copyWith(void Function(RepeatedCell) updates) => super.copyWith((message) => updates(message as RepeatedCell)) as RepeatedCell; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RepeatedCell create() => RepeatedCell._(); + RepeatedCell createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RepeatedCell getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedCell? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get items => $_getList(0); +} + class CreateGridPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateGridPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') 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 1504b31506..a6a7eb79d3 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 @@ -131,6 +131,16 @@ const Cell$json = const { /// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhgKB2NvbnRlbnQYAiABKAlSB2NvbnRlbnQ='); +@$core.Deprecated('Use repeatedCellDescriptor instead') +const RepeatedCell$json = const { + '1': 'RepeatedCell', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Cell', '10': 'items'}, + ], +}; + +/// Descriptor for `RepeatedCell`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedCellDescriptor = $convert.base64Decode('CgxSZXBlYXRlZENlbGwSGwoFaXRlbXMYASADKAsyBS5DZWxsUgVpdGVtcw=='); @$core.Deprecated('Use createGridPayloadDescriptor instead') const CreateGridPayload$json = const { '1': 'CreateGridPayload', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pb.dart new file mode 100644 index 0000000000..402c0a4115 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pb.dart @@ -0,0 +1,11 @@ +/// +// Generated code. Do not modify. +// source: dart_notification.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +export 'dart_notification.pbenum.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart new file mode 100644 index 0000000000..9f4245122f --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart @@ -0,0 +1,34 @@ +/// +// Generated code. Do not modify. +// source: dart_notification.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +// ignore_for_file: UNDEFINED_SHOWN_NAME +import 'dart:core' as $core; +import 'package:protobuf/protobuf.dart' as $pb; + +class GridNotification extends $pb.ProtobufEnum { + static const GridNotification Unknown = GridNotification._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown'); + static const GridNotification GridDidCreateRows = GridNotification._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidCreateRows'); + static const GridNotification GridDidDeleteRow = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidDeleteRow'); + static const GridNotification GridDidUpdateRows = GridNotification._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateRows'); + static const GridNotification GridDidUpdateCells = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateCells'); + static const GridNotification GridDidUpdateFields = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateFields'); + + static const $core.List values = [ + Unknown, + GridDidCreateRows, + GridDidDeleteRow, + GridDidUpdateRows, + GridDidUpdateCells, + GridDidUpdateFields, + ]; + + static final $core.Map<$core.int, GridNotification> _byValue = $pb.ProtobufEnum.initByValue(values); + static GridNotification? valueOf($core.int value) => _byValue[value]; + + const GridNotification._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart new file mode 100644 index 0000000000..5100550835 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart @@ -0,0 +1,25 @@ +/// +// Generated code. Do not modify. +// source: dart_notification.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use gridNotificationDescriptor instead') +const GridNotification$json = const { + '1': 'GridNotification', + '2': const [ + const {'1': 'Unknown', '2': 0}, + const {'1': 'GridDidCreateRows', '2': 10}, + const {'1': 'GridDidDeleteRow', '2': 11}, + const {'1': 'GridDidUpdateRows', '2': 12}, + const {'1': 'GridDidUpdateCells', '2': 20}, + const {'1': 'GridDidUpdateFields', '2': 30}, + ], +}; + +/// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIVChFHcmlkRGlkQ3JlYXRlUm93cxAKEhQKEEdyaWREaWREZWxldGVSb3cQCxIVChFHcmlkRGlkVXBkYXRlUm93cxAMEhYKEkdyaWREaWRVcGRhdGVDZWxscxAUEhcKE0dyaWREaWRVcGRhdGVGaWVsZHMQHg=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbserver.dart new file mode 100644 index 0000000000..8be819e83e --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: dart_notification.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'dart_notification.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart index 0ad090edd5..daefe6a170 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart @@ -1,6 +1,7 @@ // Auto-generated, do not edit export './date_description.pb.dart'; export './text_description.pb.dart'; +export './dart_notification.pb.dart'; export './checkbox_description.pb.dart'; export './selection_description.pb.dart'; export './event_map.pb.dart'; diff --git a/frontend/rust-lib/flowy-grid/Flowy.toml b/frontend/rust-lib/flowy-grid/Flowy.toml index 4d1a277df3..b310e3fcd7 100644 --- a/frontend/rust-lib/flowy-grid/Flowy.toml +++ b/frontend/rust-lib/flowy-grid/Flowy.toml @@ -1,3 +1,3 @@ -proto_crates = ["src/event_map.rs", "src/services/cell/description"] +proto_crates = ["src/event_map.rs", "src/services/cell/description", "src/dart_notification.rs"] event_files = ["src/event_map.rs"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs new file mode 100644 index 0000000000..d6fb15d719 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -0,0 +1,36 @@ +use dart_notify::DartNotifyBuilder; +use flowy_derive::ProtoBuf_Enum; +const OBSERVABLE_CATEGORY: &str = "Grid"; + +#[derive(ProtoBuf_Enum, Debug)] +pub enum GridNotification { + Unknown = 0, + GridDidCreateRows = 10, + GridDidDeleteRow = 11, + GridDidUpdateRows = 12, + + GridDidUpdateCells = 20, + GridDidUpdateFields = 30, +} + +impl std::default::Default for GridNotification { + fn default() -> Self { + GridNotification::Unknown + } +} + +impl std::convert::From for i32 { + fn from(notification: GridNotification) -> Self { + notification as i32 + } +} + +#[tracing::instrument(level = "trace")] +pub fn send_dart_notification(id: &str, ty: GridNotification) -> DartNotifyBuilder { + DartNotifyBuilder::new(id, ty, OBSERVABLE_CATEGORY) +} + +#[tracing::instrument(level = "trace")] +pub fn send_anonymous_dart_notification(ty: GridNotification) -> DartNotifyBuilder { + DartNotifyBuilder::new("", ty, OBSERVABLE_CATEGORY) +} diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index e92556b554..9d0001305d 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -45,11 +45,11 @@ pub(crate) async fn get_fields_handler( pub(crate) async fn create_row_handler( data: Data, manager: AppData>, -) -> DataResult { +) -> Result<(), FlowyError> { let payload: CreateRowPayload = data.into_inner(); let editor = manager.get_grid_editor(payload.grid_id.as_ref())?; - let row = editor.create_row(payload.upper_row_id).await?; - data_result(row) + let _ = editor.create_row(payload.upper_row_id).await?; + Ok(()) } #[tracing::instrument(level = "debug", skip_all, err)] diff --git a/frontend/rust-lib/flowy-grid/src/lib.rs b/frontend/rust-lib/flowy-grid/src/lib.rs index 526e1e4267..a3ac3411e2 100644 --- a/frontend/rust-lib/flowy-grid/src/lib.rs +++ b/frontend/rust-lib/flowy-grid/src/lib.rs @@ -5,6 +5,7 @@ mod event_handler; pub mod event_map; pub mod manager; +mod dart_notification; mod protobuf; pub mod services; pub mod util; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs new file mode 100644 index 0000000000..63676bd6e6 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs @@ -0,0 +1,106 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `dart_notification.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum GridNotification { + Unknown = 0, + GridDidCreateRows = 10, + GridDidDeleteRow = 11, + GridDidUpdateRows = 12, + GridDidUpdateCells = 20, + GridDidUpdateFields = 30, +} + +impl ::protobuf::ProtobufEnum for GridNotification { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(GridNotification::Unknown), + 10 => ::std::option::Option::Some(GridNotification::GridDidCreateRows), + 11 => ::std::option::Option::Some(GridNotification::GridDidDeleteRow), + 12 => ::std::option::Option::Some(GridNotification::GridDidUpdateRows), + 20 => ::std::option::Option::Some(GridNotification::GridDidUpdateCells), + 30 => ::std::option::Option::Some(GridNotification::GridDidUpdateFields), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [GridNotification] = &[ + GridNotification::Unknown, + GridNotification::GridDidCreateRows, + GridNotification::GridDidDeleteRow, + GridNotification::GridDidUpdateRows, + GridNotification::GridDidUpdateCells, + GridNotification::GridDidUpdateFields, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("GridNotification", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for GridNotification { +} + +impl ::std::default::Default for GridNotification { + fn default() -> Self { + GridNotification::Unknown + } +} + +impl ::protobuf::reflect::ProtobufValue for GridNotification { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x17dart_notification.proto*\x94\x01\n\x10GridNotification\x12\x0b\n\ + \x07Unknown\x10\0\x12\x15\n\x11GridDidCreateRows\x10\n\x12\x14\n\x10Grid\ + DidDeleteRow\x10\x0b\x12\x15\n\x11GridDidUpdateRows\x10\x0c\x12\x16\n\ + \x12GridDidUpdateCells\x10\x14\x12\x17\n\x13GridDidUpdateFields\x10\x1eb\ + \x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs index fb32dca3f2..a616a281d6 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs @@ -7,6 +7,9 @@ pub use date_description::*; mod text_description; pub use text_description::*; +mod dart_notification; +pub use dart_notification::*; + mod checkbox_description; pub use checkbox_description::*; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto new file mode 100644 index 0000000000..9c606ac091 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +enum GridNotification { + Unknown = 0; + GridDidCreateRows = 10; + GridDidDeleteRow = 11; + GridDidUpdateRows = 12; + GridDidUpdateCells = 20; + GridDidUpdateFields = 30; +} 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 0da4b9e609..8e49a47588 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 @@ -1,5 +1,5 @@ use crate::manager::GridUser; -use crate::services::row::make_row_ids_per_block; +use crate::services::row::{make_cell, make_row_ids_per_block, make_rows}; use bytes::Bytes; use dashmap::DashMap; @@ -8,7 +8,8 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - GridBlock, GridBlockChangeset, RepeatedRowOrder, RowMeta, RowMetaChangeset, RowOrder, + Cell, FieldMeta, GridBlock, GridBlockChangeset, RepeatedCell, RepeatedRow, RepeatedRowOrder, RowMeta, + RowMetaChangeset, RowOrder, }; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_sync::{ @@ -19,6 +20,7 @@ use lib_ot::core::PlainTextAttributes; use std::collections::HashMap; +use crate::dart_notification::{send_dart_notification, GridNotification}; use std::sync::Arc; use tokio::sync::RwLock; @@ -26,17 +28,20 @@ type RowId = String; type BlockId = String; pub(crate) struct GridBlockMetaEditorManager { + grid_id: String, user: Arc, editor_map: DashMap>, block_id_by_row_id: DashMap, } impl GridBlockMetaEditorManager { - pub(crate) async fn new(user: &Arc, blocks: Vec) -> FlowyResult { + pub(crate) async fn new(grid_id: &str, user: &Arc, blocks: Vec) -> FlowyResult { let editor_map = make_block_meta_editor_map(user, blocks).await?; let user = user.clone(); let block_id_by_row_id = DashMap::new(); + let grid_id = grid_id.to_owned(); let manager = Self { + grid_id, user, editor_map, block_id_by_row_id, @@ -56,25 +61,41 @@ impl GridBlockMetaEditorManager { } } - pub(crate) async fn create_row(&self, row: RowMeta, upper_row_id: Option) -> FlowyResult { - self.block_id_by_row_id.insert(row.id.clone(), row.block_id.clone()); - let editor = self.get_editor(&row.block_id).await?; - editor.create_row(row, upper_row_id).await + pub(crate) async fn create_row( + &self, + field_metas: &[FieldMeta], + row_meta: RowMeta, + upper_row_id: Option, + ) -> FlowyResult { + self.block_id_by_row_id + .insert(row_meta.id.clone(), row_meta.block_id.clone()); + let editor = self.get_editor(&row_meta.block_id).await?; + + let rows = make_rows(field_metas, vec![row_meta.clone().into()]); + send_dart_notification(&self.grid_id, GridNotification::GridDidCreateRows) + .payload(RepeatedRow::from(rows)) + .send(); + + self.notify_did_create_rows(field_metas, vec![row_meta.clone()]); + + editor.create_row(row_meta, upper_row_id).await } pub(crate) async fn insert_row( &self, + field_metas: &[FieldMeta], rows_by_block_id: HashMap>, ) -> FlowyResult> { let mut changesets = vec![]; - for (block_id, rows) in rows_by_block_id { + for (block_id, row_metas) in rows_by_block_id { let editor = self.get_editor(&block_id).await?; let mut row_count = 0; - for row in rows { + for row in &row_metas { self.block_id_by_row_id.insert(row.id.clone(), row.block_id.clone()); - row_count = editor.create_row(row, None).await?; + row_count = editor.create_row(row.clone(), None).await?; } changesets.push(GridBlockChangeset::from_row_count(&block_id, row_count)); + self.notify_did_create_rows(field_metas, row_metas); } Ok(changesets) @@ -104,19 +125,17 @@ impl GridBlockMetaEditorManager { } pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { - match self.block_id_by_row_id.get(&changeset.row_id) { - None => { - let msg = format!( - "Update Row failed. Can't find the corresponding block with row_id: {}", - changeset.row_id - ); - Err(FlowyError::internal().context(msg)) - } - Some(block_id) => { - let editor = self.get_editor(&block_id).await?; - editor.update_row(changeset).await - } - } + let editor = self.get_editor_from_row_id(&changeset.row_id).await?; + let _ = editor.update_row(changeset.clone()).await?; + let _ = self.notify_did_update_row()?; + Ok(()) + } + + pub async fn update_cells(&self, field_metas: &[FieldMeta], changeset: RowMetaChangeset) -> FlowyResult<()> { + let editor = self.get_editor_from_row_id(&changeset.row_id).await?; + let _ = editor.update_row(changeset.clone()).await?; + self.notify_did_update_cells(changeset, field_metas)?; + Ok(()) } pub(crate) async fn get_all_rows(&self, grid_blocks: Vec) -> FlowyResult>> { @@ -159,6 +178,68 @@ impl GridBlockMetaEditorManager { } Ok(row_metas) } + + async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { + match self.block_id_by_row_id.get(row_id) { + None => { + let msg = format!( + "Update Row failed. Can't find the corresponding block with row_id: {}", + row_id + ); + Err(FlowyError::internal().context(msg)) + } + Some(block_id) => { + let editor = self.get_editor(&block_id).await?; + Ok(editor) + } + } + } + + fn notify_did_create_rows(&self, field_metas: &[FieldMeta], row_metas: Vec) { + let rows = make_rows( + field_metas, + row_metas + .into_iter() + .map(|row_meta| Arc::new(row_meta)) + .collect::>(), + ); + send_dart_notification(&self.grid_id, GridNotification::GridDidCreateRows) + .payload(RepeatedRow::from(rows)) + .send(); + } + + fn notify_did_update_row(&self) -> FlowyResult<()> { + // send_dart_notification(&changeset.row_id, GridNotification::GridDidUpdateRows) + // .payload(RepeatedRow::from(cells)) + // .send(); + + todo!() + } + + fn notify_did_update_cells(&self, changeset: RowMetaChangeset, field_metas: &[FieldMeta]) -> FlowyResult<()> { + let field_meta_map = field_metas + .iter() + .map(|field_meta| (&field_meta.id, field_meta)) + .collect::>(); + + let mut cells = vec![]; + changeset + .cell_by_field_id + .into_iter() + .for_each( + |(field_id, cell_meta)| match make_cell(&field_meta_map, field_id, cell_meta) { + None => {} + Some((_, cell)) => cells.push(cell), + }, + ); + + if !cells.is_empty() { + send_dart_notification(&changeset.row_id, GridNotification::GridDidUpdateCells) + .payload(RepeatedCell::from(cells)) + .send(); + } + Ok(()) + } } async fn make_block_meta_editor_map( 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 f6730565ed..491a2831bb 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,16 +1,17 @@ use crate::manager::GridUser; use crate::services::block_meta_editor::GridBlockMetaEditorManager; use bytes::Bytes; -use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; +use flowy_collaboration::client_grid::{GridChangeset, GridMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - CellMetaChangeset, FieldChangeset, FieldMeta, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, - RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, + Cell, CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlock, GridBlockChangeset, RepeatedField, + RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, }; use std::collections::HashMap; +use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::services::row::{ make_row_by_row_id, make_rows, row_meta_from_context, serialize_cell_data, RowMetaContext, RowMetaContextBuilder, }; @@ -40,8 +41,9 @@ impl ClientGridEditor { let rev_manager = Arc::new(rev_manager); let grid_meta_pad = Arc::new(RwLock::new(grid_pad)); - let block_meta_manager = - Arc::new(GridBlockMetaEditorManager::new(&user, grid_meta_pad.read().await.get_blocks().clone()).await?); + let block_meta_manager = Arc::new( + GridBlockMetaEditorManager::new(grid_id, &user, grid_meta_pad.read().await.get_blocks().clone()).await?, + ); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), @@ -54,6 +56,7 @@ impl ClientGridEditor { pub async fn create_field(&self, field_meta: FieldMeta) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.create_field(field_meta)?)).await?; + let _ = self.notify_did_update_fields().await?; Ok(()) } @@ -81,7 +84,7 @@ impl ClientGridEditor { Ok(()) } - pub async fn create_row(&self, upper_row_id: Option) -> FlowyResult { + pub async fn create_row(&self, upper_row_id: Option) -> FlowyResult<()> { let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?; let block_id = self.last_block_id().await?; @@ -92,17 +95,17 @@ impl ClientGridEditor { // insert the row let row_count = self .block_meta_manager - .create_row(row_meta.clone(), upper_row_id) + .create_row(&field_metas, row_meta, upper_row_id) .await?; - let row = make_rows(&field_metas, vec![row_meta.into()]).pop().unwrap(); // update block row count let changeset = GridBlockChangeset::from_row_count(&block_id, row_count); let _ = self.update_block(changeset).await?; - Ok(row) + Ok(()) } pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult<()> { + let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?; let block_id = self.last_block_id().await?; let mut rows_by_block_id: HashMap> = HashMap::new(); for ctx in contexts { @@ -112,7 +115,10 @@ 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_meta_manager + .insert_row(&field_metas, rows_by_block_id) + .await?; for changeset in changesets { let _ = self.update_block(changeset).await?; } @@ -136,8 +142,13 @@ impl ClientGridEditor { } } + let field_metas = self.get_field_metas(None).await?; let row_changeset: RowMetaChangeset = changeset.into(); - self.update_row(row_changeset).await + let _ = self + .block_meta_manager + .update_cells(&field_metas, row_changeset) + .await?; + Ok(()) } pub async fn get_rows(&self, row_orders: Option) -> FlowyResult> { @@ -205,7 +216,7 @@ impl ClientGridEditor { async fn modify(&self, f: F) -> FlowyResult<()> where - F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult>, + F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult>, { let mut write_guard = self.grid_meta_pad.write().await; match f(&mut *write_guard)? { @@ -217,8 +228,8 @@ impl ClientGridEditor { Ok(()) } - async fn apply_change(&self, change: GridChange) -> FlowyResult<()> { - let GridChange { delta, md5 } = change; + async fn apply_change(&self, change: GridChangeset) -> FlowyResult<()> { + let GridChangeset { delta, md5 } = change; let user_id = self.user.user_id()?; let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); let delta_data = delta.to_delta_bytes(); @@ -243,6 +254,15 @@ impl ClientGridEditor { Some(grid_block) => Ok(grid_block.id.clone()), } } + + async fn notify_did_update_fields(&self) -> FlowyResult<()> { + let field_metas = self.get_field_metas(None).await?; + let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::>().into(); + send_dart_notification(&self.grid_id, GridNotification::GridDidUpdateFields) + .payload(repeated_field) + .send(); + Ok(()) + } } #[cfg(feature = "flowy_unit_test")] 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 02a6f760e0..6283db0540 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 @@ -48,7 +48,11 @@ pub(crate) fn make_rows(fields: &[FieldMeta], row_metas: Vec>) -> V } #[inline(always)] -fn make_cell(field_map: &HashMap<&String, &FieldMeta>, field_id: String, raw_cell: CellMeta) -> Option<(String, Cell)> { +pub fn make_cell( + field_map: &HashMap<&String, &FieldMeta>, + field_id: String, + raw_cell: CellMeta, +) -> Option<(String, Cell)> { let field_meta = field_map.get(&field_id)?; match deserialize_cell_data(raw_cell.data, field_meta) { Ok(content) => { @@ -63,9 +67,9 @@ fn make_cell(field_map: &HashMap<&String, &FieldMeta>, field_id: String, raw_cel } pub(crate) fn make_row_by_row_id(fields: &[FieldMeta], row_metas: Vec>) -> HashMap { - let field_map = fields + let field_meta_map = fields .iter() - .map(|field| (&field.id, field)) + .map(|field_meta| (&field_meta.id, field_meta)) .collect::>(); let make_row = |row_meta: Arc| { @@ -73,7 +77,7 @@ pub(crate) fn make_row_by_row_id(fields: &[FieldMeta], row_metas: Vec>(); let row = Row { diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index a9bc34c18c..6449d09f6f 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -172,7 +172,7 @@ impl GridEditorTest { assert_eq!(compared_block, block); } EditorScript::CreateEmptyRow => { - self.editor.create_row().await.unwrap(); + self.editor.create_row(None).await.unwrap(); self.row_metas = self.editor.get_row_metas(None).await.unwrap(); self.grid_blocks = self.editor.get_blocks().await.unwrap(); } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs index e836034fae..a403b9c1c9 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs @@ -35,7 +35,7 @@ impl GridMetaPad { Self::from_delta(grid_delta) } - pub fn create_field(&mut self, field_meta: FieldMeta) -> CollaborateResult> { + pub fn create_field(&mut self, field_meta: FieldMeta) -> CollaborateResult> { self.modify_grid(|grid| { if grid.fields.contains(&field_meta) { tracing::warn!("Duplicate grid field"); @@ -47,7 +47,7 @@ impl GridMetaPad { }) } - pub fn delete_field(&mut self, field_id: &str) -> CollaborateResult> { + pub fn delete_field(&mut self, field_id: &str) -> CollaborateResult> { self.modify_grid(|grid| match grid.fields.iter().position(|field| field.id == field_id) { None => Ok(None), Some(index) => { @@ -95,7 +95,7 @@ impl GridMetaPad { } } - pub fn update_field(&mut self, changeset: FieldChangeset) -> CollaborateResult> { + pub fn update_field(&mut self, changeset: FieldChangeset) -> CollaborateResult> { let field_id = changeset.field_id.clone(); self.modify_field(&field_id, |field| { let mut is_changed = None; @@ -138,7 +138,7 @@ impl GridMetaPad { }) } - pub fn create_block(&mut self, block: GridBlock) -> CollaborateResult> { + pub fn create_block(&mut self, block: GridBlock) -> CollaborateResult> { self.modify_grid(|grid| { if grid.blocks.iter().any(|b| b.id == block.id) { tracing::warn!("Duplicate grid block"); @@ -165,7 +165,7 @@ impl GridMetaPad { self.grid_meta.blocks.clone() } - pub fn update_block(&mut self, changeset: GridBlockChangeset) -> CollaborateResult> { + pub fn update_block(&mut self, changeset: GridBlockChangeset) -> CollaborateResult> { let block_id = changeset.block_id.clone(); self.modify_block(&block_id, |block| { let mut is_changed = None; @@ -200,7 +200,7 @@ impl GridMetaPad { &self.grid_meta.fields } - fn modify_grid(&mut self, f: F) -> CollaborateResult> + fn modify_grid(&mut self, f: F) -> CollaborateResult> where F: FnOnce(&mut GridMeta) -> CollaborateResult>, { @@ -214,14 +214,14 @@ impl GridMetaPad { None => Ok(None), Some(delta) => { self.delta = self.delta.compose(&delta)?; - Ok(Some(GridChange { delta, md5: self.md5() })) + Ok(Some(GridChangeset { delta, md5: self.md5() })) } } } } } - pub fn modify_block(&mut self, block_id: &str, f: F) -> CollaborateResult> + pub fn modify_block(&mut self, block_id: &str, f: F) -> CollaborateResult> where F: FnOnce(&mut GridBlock) -> CollaborateResult>, { @@ -234,7 +234,7 @@ impl GridMetaPad { }) } - pub fn modify_field(&mut self, field_id: &str, f: F) -> CollaborateResult> + pub fn modify_field(&mut self, field_id: &str, f: F) -> CollaborateResult> where F: FnOnce(&mut FieldMeta) -> CollaborateResult>, { @@ -254,7 +254,7 @@ fn json_from_grid(grid: &Arc) -> CollaborateResult { Ok(json) } -pub struct GridChange { +pub struct GridChangeset { pub delta: GridMetaDelta, /// md5: the md5 of the grid after applying the change. pub md5: String, 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 441cc7d39e..36e8e211e3 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -204,6 +204,31 @@ impl Cell { } } +#[derive(Debug, Default, ProtoBuf)] +pub struct RepeatedCell { + #[pb(index = 1)] + pub items: Vec, +} + +impl std::ops::Deref for RepeatedCell { + type Target = Vec; + fn deref(&self) -> &Self::Target { + &self.items + } +} + +impl std::ops::DerefMut for RepeatedCell { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.items + } +} + +impl std::convert::From> for RepeatedCell { + fn from(items: Vec) -> Self { + Self { items } + } +} + #[derive(ProtoBuf, Default)] pub struct CreateGridPayload { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index abe55edbad..9702766975 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 @@ -2115,6 +2115,172 @@ impl ::protobuf::reflect::ProtobufValue for Cell { } } +#[derive(PartialEq,Clone,Default)] +pub struct RepeatedCell { + // message fields + pub items: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RepeatedCell { + fn default() -> &'a RepeatedCell { + ::default_instance() + } +} + +impl RepeatedCell { + pub fn new() -> RepeatedCell { + ::std::default::Default::default() + } + + // repeated .Cell items = 1; + + + pub fn get_items(&self) -> &[Cell] { + &self.items + } + pub fn clear_items(&mut self) { + self.items.clear(); + } + + // Param is passed by value, moved + pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { + self.items = v; + } + + // Mutable pointer to the field. + pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.items + } + + // Take field + pub fn take_items(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for RepeatedCell { + fn is_initialized(&self) -> bool { + for v in &self.items { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.items { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.items { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RepeatedCell { + RepeatedCell::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "items", + |m: &RepeatedCell| { &m.items }, + |m: &mut RepeatedCell| { &mut m.items }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedCell", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RepeatedCell { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedCell::new) + } +} + +impl ::protobuf::Clear for RepeatedCell { + fn clear(&mut self) { + self.items.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RepeatedCell { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RepeatedCell { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct CreateGridPayload { // message fields @@ -3129,16 +3295,17 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\ \x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05items\";\n\x04Cell\x12\ \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\ - \x18\x02\x20\x01(\tR\x07content\"'\n\x11CreateGridPayload\x12\x12\n\x04n\ - ame\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\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\x0cupper_row_id\x18\x02\x20\x01(\ - \tH\0R\nupperRowIdB\x15\n\x13one_of_upper_row_id\"d\n\x11QueryFieldPaylo\ - ad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_or\ - ders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\\\n\ - \x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ - \x120\n\nrow_orders\x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrderR\trowOrde\ - rsb\x06proto3\ + \x18\x02\x20\x01(\tR\x07content\"+\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\ + \x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\ + \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cupper_row_id\x18\ + \x02\x20\x01(\tH\0R\nupperRowIdB\x15\n\x13one_of_upper_row_id\"d\n\x11Qu\ + eryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\ + \n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfiel\ + dOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\t\ + R\x06gridId\x120\n\nrow_orders\x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrde\ + rR\trowOrdersb\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 7f01016174..ed6fc83b65 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 @@ -43,6 +43,9 @@ message Cell { string field_id = 1; string content = 2; } +message RepeatedCell { + repeated Cell items = 1; +} message CreateGridPayload { string name = 1; } From 4730ca9302a92058f64922b4bc0f278d186acd7c Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 17 Mar 2022 17:25:43 +0800 Subject: [PATCH 25/28] chore: refactor grid block --- .../lib/startup/home_deps_resolver.dart | 2 + .../lib/workspace/application/grid/data.dart | 4 +- .../workspace/application/grid/grid_bloc.dart | 22 +- .../application/grid/grid_listener.dart | 21 +- .../application/grid/grid_service.dart | 10 +- .../workspace/application/grid/row_bloc.dart | 27 +- .../application/grid/row_listener.dart | 54 ++ .../dart_event/flowy-grid/dart_event.dart | 12 +- .../flowy-grid-data-model/grid.pb.dart | 190 +++-- .../flowy-grid-data-model/grid.pbjson.dart | 49 +- .../flowy-grid-data-model/meta.pb.dart | 194 ++--- .../flowy-grid-data-model/meta.pbjson.dart | 38 +- .../flowy-grid/dart_notification.pbenum.dart | 8 +- .../flowy-grid/dart_notification.pbjson.dart | 6 +- .../protobuf/flowy-grid/event_map.pbenum.dart | 4 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 4 +- .../flowy-grid/src/dart_notification.rs | 4 +- .../rust-lib/flowy-grid/src/event_handler.rs | 16 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 6 +- frontend/rust-lib/flowy-grid/src/manager.rs | 4 +- .../src/protobuf/model/dart_notification.rs | 20 +- .../src/protobuf/model/event_map.rs | 12 +- .../protobuf/proto/dart_notification.proto | 4 +- .../src/protobuf/proto/event_map.proto | 2 +- .../src/services/block_meta_editor.rs | 179 +++-- .../flowy-grid/src/services/grid_editor.rs | 114 +-- .../flowy-grid/src/services/row/row_loader.rs | 110 ++- .../flowy-grid/tests/grid/grid_test.rs | 12 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 24 +- ...ock_pad.rs => grid_block_meta_data_pad.rs} | 64 +- .../src/client_grid/grid_builder.rs | 10 +- .../src/client_grid/grid_meta_pad.rs | 28 +- .../src/client_grid/mod.rs | 4 +- .../src/entities/grid.rs | 67 +- .../src/entities/meta.rs | 36 +- .../src/protobuf/model/grid.rs | 604 ++++++++++++--- .../src/protobuf/model/meta.rs | 707 +++++++++--------- .../src/protobuf/proto/grid.proto | 17 +- .../src/protobuf/proto/meta.proto | 18 +- 39 files changed, 1657 insertions(+), 1050 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/row_listener.dart rename shared-lib/flowy-collaboration/src/client_grid/{block_pad.rs => grid_block_meta_data_pad.rs} (85%) diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index d66fe7cc01..084612ca61 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -3,6 +3,7 @@ import 'package:app_flowy/user/application/user_service.dart'; import 'package:app_flowy/workspace/application/app/prelude.dart'; import 'package:app_flowy/workspace/application/doc/prelude.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/application/grid/row_listener.dart'; import 'package:app_flowy/workspace/application/trash/prelude.dart'; import 'package:app_flowy/workspace/application/workspace/prelude.dart'; import 'package:app_flowy/workspace/application/view/prelude.dart'; @@ -98,6 +99,7 @@ class HomeDepsResolver { getIt.registerFactoryParam( (data, _) => RowBloc( service: RowService(data), + listener: RowListener(rowId: data.row.id), ), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart index 77cb1d9e6d..05ca053b8c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -3,12 +3,12 @@ import 'package:equatable/equatable.dart'; class GridInfo { final String gridId; - List rows; + List gridBlocks; List fields; GridInfo({ required this.gridId, - required this.rows, + required this.gridBlocks, required this.fields, }); diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart index 09e4428a83..8fea0b04df 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -14,8 +14,8 @@ import 'grid_service.dart'; part 'grid_bloc.freezed.dart'; class GridBloc extends Bloc { - final GridService service; final View view; + final GridService service; final GridListener listener; Grid? _grid; List? _fields; @@ -49,9 +49,9 @@ class GridBloc extends Bloc { Future _startGridListening() async { listener.createRowNotifier.addPublishListener((result) { - result.fold((row) { + result.fold((repeatedRow) { // - Log.info("$row"); + Log.info("$repeatedRow"); }, (err) => null); }); @@ -91,10 +91,18 @@ class GridBloc extends Bloc { Future _loadGridInfo(Emitter emit) async { final grid = _grid; if (grid != null && _fields != null) { - final result = await service.getRows(gridId: grid.id, rowOrders: grid.rowOrders); - result.fold((repeatedRow) { - final rows = repeatedRow.items; - final gridInfo = GridInfo(gridId: grid.id, rows: rows, fields: _fields!); + final result = await service.getGridBlocks( + gridId: grid.id, + blocks: grid.blocks, + ); + + result.fold((repeatedGridBlock) { + final blocks = repeatedGridBlock.items; + final gridInfo = GridInfo( + gridId: grid.id, + blocks: blocks, + fields: _fields!, + ); emit( state.copyWith(loadingState: GridLoadingState.finish(left(unit)), gridInfo: some(left(gridInfo))), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart index b17544edf9..67f69b57b6 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart @@ -9,13 +9,11 @@ import 'dart:typed_data'; import 'package:app_flowy/core/notification_helper.dart'; import 'package:dartz/dartz.dart'; -typedef CreateRowNotifiedValue = Either; -typedef DeleteRowNotifierValue = Either; +typedef GridBlockUpdateNotifiedValue = Either; class GridListener { final String gridId; - PublishNotifier createRowNotifier = PublishNotifier(); - PublishNotifier deleteRowNotifier = PublishNotifier(); + PublishNotifier blockUpdateNotifier = PublishNotifier(); StreamSubscription? _subscription; late GridNotificationParser _parser; @@ -34,16 +32,10 @@ class GridListener { void _handleObservableType(GridNotification ty, Either result) { switch (ty) { - case GridNotification.GridDidCreateRows: + case GridNotification.GridDidUpdateBlock: result.fold( - (payload) => createRowNotifier.value = left(RepeatedRow.fromBuffer(payload)), - (error) => createRowNotifier.value = right(error), - ); - break; - case GridNotification.GridDidDeleteRow: - result.fold( - (payload) => deleteRowNotifier.value = left(RepeatedRow.fromBuffer(payload)), - (error) => deleteRowNotifier.value = right(error), + (payload) => blockUpdateNotifier.value = left(GridBlockId.fromBuffer(payload)), + (error) => blockUpdateNotifier.value = right(error), ); break; @@ -54,7 +46,6 @@ class GridListener { Future close() async { await _subscription?.cancel(); - createRowNotifier.dispose(); - deleteRowNotifier.dispose(); + blockUpdateNotifier.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index 915cc671b6..62208c8d05 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -3,6 +3,7 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; class GridService { Future> openGrid({required String gridId}) async { @@ -18,11 +19,12 @@ class GridService { return GridEventCreateRow(payload).send(); } - Future> getRows({required String gridId, required List rowOrders}) { - final payload = QueryRowPayload.create() + Future> getGridBlocks( + {required String gridId, required List blocks}) { + final payload = QueryGridBlocksPayload.create() ..gridId = gridId - ..rowOrders = RepeatedRowOrder(items: rowOrders); - return GridEventGetRows(payload).send(); + ..blocks.addAll(blocks); + return GridEventGetGridBlocks(payload).send(); } Future> getFields({required String gridId, required List fieldOrders}) { diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart index 1dd20aad9a..16195af592 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart @@ -1,19 +1,24 @@ +import 'package:flowy_sdk/log.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; import 'data.dart'; +import 'row_listener.dart'; import 'row_service.dart'; part 'row_bloc.freezed.dart'; class RowBloc extends Bloc { final RowService service; + final RowListener listener; - RowBloc({required this.service}) : super(RowState.initial(service.rowData)) { + RowBloc({required this.service, required this.listener}) : super(RowState.initial(service.rowData)) { on( (event, emit) async { await event.map( - initial: (_InitialRow value) async {}, + initial: (_InitialRow value) async { + _startRowListening(); + }, createRow: (_CreateRow value) { service.createRow(); }, @@ -30,8 +35,26 @@ class RowBloc extends Bloc { @override Future close() async { + await listener.close(); return super.close(); } + + Future _startRowListening() async { + listener.updateRowNotifier.addPublishListener((result) { + result.fold((row) { + // + }, (err) => null); + }); + + listener.updateCellNotifier.addPublishListener((result) { + result.fold((repeatedCvell) { + // + Log.info("$repeatedCvell"); + }, (r) => null); + }); + + listener.start(); + } } @freezed diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/row_listener.dart new file mode 100644 index 0000000000..76a2ba617d --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/row_listener.dart @@ -0,0 +1,54 @@ +import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; +import 'package:flowy_sdk/rust_stream.dart'; +import 'package:flowy_infra/notifier.dart'; +import 'dart:async'; +import 'dart:typed_data'; +import 'package:app_flowy/core/notification_helper.dart'; +import 'package:dartz/dartz.dart'; + +typedef UpdateCellNotifiedValue = Either; +typedef UpdateRowNotifiedValue = Either; + +class RowListener { + final String rowId; + PublishNotifier updateCellNotifier = PublishNotifier(); + PublishNotifier updateRowNotifier = PublishNotifier(); + StreamSubscription? _subscription; + late GridNotificationParser _parser; + + RowListener({required this.rowId}); + + void start() { + _parser = GridNotificationParser( + id: rowId, + callback: (ty, result) { + _handleObservableType(ty, result); + }, + ); + + _subscription = RustStreamReceiver.listen((observable) => _parser.parse(observable)); + } + + void _handleObservableType(GridNotification ty, Either result) { + switch (ty) { + case GridNotification.GridDidUpdateCells: + result.fold( + (payload) => updateCellNotifier.value = left(RepeatedCell.fromBuffer(payload)), + (error) => updateCellNotifier.value = right(error), + ); + break; + + default: + break; + } + } + + Future close() async { + await _subscription?.cancel(); + updateCellNotifier.dispose(); + updateRowNotifier.dispose(); + } +} 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 19c46c8306..10cb8bae79 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 @@ -18,18 +18,18 @@ class GridEventGetGridData { } } -class GridEventGetRows { - QueryRowPayload request; - GridEventGetRows(this.request); +class GridEventGetGridBlocks { + QueryGridBlocksPayload request; + GridEventGetGridBlocks(this.request); - Future> send() { + Future> send() { final request = FFIRequest.create() - ..event = GridEvent.GetRows.toString() + ..event = GridEvent.GetGridBlocks.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) .then((bytesResult) => bytesResult.fold( - (okBytes) => left(RepeatedRow.fromBuffer(okBytes)), + (okBytes) => left(RepeatedGridBlock.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 21f7e0f4a8..9b4dc19b7c 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 @@ -9,13 +9,15 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; +import 'meta.pb.dart' as $0; + import 'meta.pbenum.dart' as $0; class Grid extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Grid', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', $pb.PbFieldType.PM, subBuilder: FieldOrder.create) - ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', $pb.PbFieldType.PM, subBuilder: RowOrder.create) + ..pc<$0.GridBlockMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: $0.GridBlockMeta.create) ..hasRequiredFields = false ; @@ -23,7 +25,7 @@ class Grid extends $pb.GeneratedMessage { factory Grid({ $core.String? id, $core.Iterable? fieldOrders, - $core.Iterable? rowOrders, + $core.Iterable<$0.GridBlockMeta>? blocks, }) { final _result = create(); if (id != null) { @@ -32,8 +34,8 @@ class Grid extends $pb.GeneratedMessage { if (fieldOrders != null) { _result.fieldOrders.addAll(fieldOrders); } - if (rowOrders != null) { - _result.rowOrders.addAll(rowOrders); + if (blocks != null) { + _result.blocks.addAll(blocks); } return _result; } @@ -71,7 +73,7 @@ class Grid extends $pb.GeneratedMessage { $core.List get fieldOrders => $_getList(1); @$pb.TagNumber(3) - $core.List get rowOrders => $_getList(2); + $core.List<$0.GridBlockMeta> get blocks => $_getList(2); } class Field extends $pb.GeneratedMessage { @@ -505,15 +507,15 @@ class Row extends $pb.GeneratedMessage { void clearHeight() => clearField(3); } -class RepeatedRow extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedRow', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Row.create) +class RepeatedGridBlock extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedGridBlock', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: GridBlock.create) ..hasRequiredFields = false ; - RepeatedRow._() : super(); - factory RepeatedRow({ - $core.Iterable? items, + RepeatedGridBlock._() : super(); + factory RepeatedGridBlock({ + $core.Iterable? items, }) { final _result = create(); if (items != null) { @@ -521,29 +523,84 @@ class RepeatedRow extends $pb.GeneratedMessage { } return _result; } - factory RepeatedRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RepeatedRow.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory RepeatedGridBlock.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedGridBlock.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - RepeatedRow clone() => RepeatedRow()..mergeFromMessage(this); + RepeatedGridBlock clone() => RepeatedGridBlock()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - RepeatedRow copyWith(void Function(RepeatedRow) updates) => super.copyWith((message) => updates(message as RepeatedRow)) as RepeatedRow; // ignore: deprecated_member_use + RepeatedGridBlock copyWith(void Function(RepeatedGridBlock) updates) => super.copyWith((message) => updates(message as RepeatedGridBlock)) as RepeatedGridBlock; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static RepeatedRow create() => RepeatedRow._(); - RepeatedRow createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static RepeatedGridBlock create() => RepeatedGridBlock._(); + RepeatedGridBlock createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static RepeatedRow getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RepeatedRow? _defaultInstance; + static RepeatedGridBlock getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedGridBlock? _defaultInstance; @$pb.TagNumber(1) - $core.List get items => $_getList(0); + $core.List get items => $_getList(0); +} + +class GridBlock extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: Row.create) + ..hasRequiredFields = false + ; + + GridBlock._() : super(); + factory GridBlock({ + $core.String? blockId, + $core.Iterable? rows, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + if (rows != null) { + _result.rows.addAll(rows); + } + return _result; + } + factory GridBlock.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlock.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + GridBlock clone() => GridBlock()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridBlock copyWith(void Function(GridBlock) updates) => super.copyWith((message) => updates(message as GridBlock)) as GridBlock; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridBlock create() => GridBlock._(); + GridBlock createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridBlock getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlock? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); + + @$pb.TagNumber(2) + $core.List get rows => $_getList(1); } class Cell extends $pb.GeneratedMessage { @@ -742,6 +799,53 @@ class GridId extends $pb.GeneratedMessage { void clearValue() => clearField(1); } +class GridBlockId extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockId', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value') + ..hasRequiredFields = false + ; + + GridBlockId._() : super(); + factory GridBlockId({ + $core.String? value, + }) { + final _result = create(); + if (value != null) { + _result.value = value; + } + return _result; + } + factory GridBlockId.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlockId.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + GridBlockId clone() => GridBlockId()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridBlockId copyWith(void Function(GridBlockId) updates) => super.copyWith((message) => updates(message as GridBlockId)) as GridBlockId; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridBlockId create() => GridBlockId._(); + GridBlockId createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridBlockId getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlockId? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get value => $_getSZ(0); + @$pb.TagNumber(1) + set value($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasValue() => $_has(0); + @$pb.TagNumber(1) + void clearValue() => clearField(1); +} + enum CreateRowPayload_OneOfUpperRowId { upperRowId, notSet @@ -879,47 +983,47 @@ class QueryFieldPayload extends $pb.GeneratedMessage { RepeatedFieldOrder ensureFieldOrders() => $_ensure(1); } -class QueryRowPayload extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryRowPayload', createEmptyInstance: create) +class QueryGridBlocksPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryGridBlocksPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', subBuilder: RepeatedRowOrder.create) + ..pc<$0.GridBlockMeta>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: $0.GridBlockMeta.create) ..hasRequiredFields = false ; - QueryRowPayload._() : super(); - factory QueryRowPayload({ + QueryGridBlocksPayload._() : super(); + factory QueryGridBlocksPayload({ $core.String? gridId, - RepeatedRowOrder? rowOrders, + $core.Iterable<$0.GridBlockMeta>? blocks, }) { final _result = create(); if (gridId != null) { _result.gridId = gridId; } - if (rowOrders != null) { - _result.rowOrders = rowOrders; + if (blocks != null) { + _result.blocks.addAll(blocks); } return _result; } - factory QueryRowPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory QueryRowPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory QueryGridBlocksPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory QueryGridBlocksPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - QueryRowPayload clone() => QueryRowPayload()..mergeFromMessage(this); + QueryGridBlocksPayload clone() => QueryGridBlocksPayload()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - QueryRowPayload copyWith(void Function(QueryRowPayload) updates) => super.copyWith((message) => updates(message as QueryRowPayload)) as QueryRowPayload; // ignore: deprecated_member_use + QueryGridBlocksPayload copyWith(void Function(QueryGridBlocksPayload) updates) => super.copyWith((message) => updates(message as QueryGridBlocksPayload)) as QueryGridBlocksPayload; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static QueryRowPayload create() => QueryRowPayload._(); - QueryRowPayload createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static QueryGridBlocksPayload create() => QueryGridBlocksPayload._(); + QueryGridBlocksPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static QueryRowPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static QueryRowPayload? _defaultInstance; + static QueryGridBlocksPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static QueryGridBlocksPayload? _defaultInstance; @$pb.TagNumber(1) $core.String get gridId => $_getSZ(0); @@ -931,14 +1035,6 @@ class QueryRowPayload extends $pb.GeneratedMessage { void clearGridId() => clearField(1); @$pb.TagNumber(2) - RepeatedRowOrder get rowOrders => $_getN(1); - @$pb.TagNumber(2) - set rowOrders(RepeatedRowOrder v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasRowOrders() => $_has(1); - @$pb.TagNumber(2) - void clearRowOrders() => clearField(2); - @$pb.TagNumber(2) - RepeatedRowOrder ensureRowOrders() => $_ensure(1); + $core.List<$0.GridBlockMeta> get blocks => $_getList(1); } 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 a6a7eb79d3..97d52d827f 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 @@ -14,12 +14,12 @@ const Grid$json = const { '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'field_orders', '3': 2, '4': 3, '5': 11, '6': '.FieldOrder', '10': 'fieldOrders'}, - const {'1': 'row_orders', '3': 3, '4': 3, '5': 11, '6': '.RowOrder', '10': 'rowOrders'}, + const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'}, ], }; /// Descriptor for `Grid`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxIoCgpyb3dfb3JkZXJzGAMgAygLMgkuUm93T3JkZXJSCXJvd09yZGVycw=='); +final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxImCgZibG9ja3MYAyADKAsyDi5HcmlkQmxvY2tNZXRhUgZibG9ja3M='); @$core.Deprecated('Use fieldDescriptor instead') const Field$json = const { '1': 'Field', @@ -110,16 +110,27 @@ const Row_CellByFieldIdEntry$json = const { /// Descriptor for `Row`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List rowDescriptor = $convert.base64Decode('CgNSb3cSDgoCaWQYASABKAlSAmlkEkAKEGNlbGxfYnlfZmllbGRfaWQYAiADKAsyFy5Sb3cuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgDIAEoBVIGaGVpZ2h0GkcKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIbCgV2YWx1ZRgCIAEoCzIFLkNlbGxSBXZhbHVlOgI4AQ=='); -@$core.Deprecated('Use repeatedRowDescriptor instead') -const RepeatedRow$json = const { - '1': 'RepeatedRow', +@$core.Deprecated('Use repeatedGridBlockDescriptor instead') +const RepeatedGridBlock$json = const { + '1': 'RepeatedGridBlock', '2': const [ - const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Row', '10': 'items'}, + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.GridBlock', '10': 'items'}, ], }; -/// Descriptor for `RepeatedRow`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List repeatedRowDescriptor = $convert.base64Decode('CgtSZXBlYXRlZFJvdxIaCgVpdGVtcxgBIAMoCzIELlJvd1IFaXRlbXM='); +/// Descriptor for `RepeatedGridBlock`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedGridBlockDescriptor = $convert.base64Decode('ChFSZXBlYXRlZEdyaWRCbG9jaxIgCgVpdGVtcxgBIAMoCzIKLkdyaWRCbG9ja1IFaXRlbXM='); +@$core.Deprecated('Use gridBlockDescriptor instead') +const GridBlock$json = const { + '1': 'GridBlock', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.Row', '10': 'rows'}, + ], +}; + +/// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSGAoEcm93cxgCIAMoCzIELlJvd1IEcm93cw=='); @$core.Deprecated('Use cellDescriptor instead') const Cell$json = const { '1': 'Cell', @@ -161,6 +172,16 @@ const GridId$json = const { /// Descriptor for `GridId`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridIdDescriptor = $convert.base64Decode('CgZHcmlkSWQSFAoFdmFsdWUYASABKAlSBXZhbHVl'); +@$core.Deprecated('Use gridBlockIdDescriptor instead') +const GridBlockId$json = const { + '1': 'GridBlockId', + '2': const [ + const {'1': 'value', '3': 1, '4': 1, '5': 9, '10': 'value'}, + ], +}; + +/// Descriptor for `GridBlockId`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockIdDescriptor = $convert.base64Decode('CgtHcmlkQmxvY2tJZBIUCgV2YWx1ZRgBIAEoCVIFdmFsdWU='); @$core.Deprecated('Use createRowPayloadDescriptor instead') const CreateRowPayload$json = const { '1': 'CreateRowPayload', @@ -186,14 +207,14 @@ const QueryFieldPayload$json = const { /// Descriptor for `QueryFieldPayload`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List queryFieldPayloadDescriptor = $convert.base64Decode('ChFRdWVyeUZpZWxkUGF5bG9hZBIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSNgoMZmllbGRfb3JkZXJzGAIgASgLMhMuUmVwZWF0ZWRGaWVsZE9yZGVyUgtmaWVsZE9yZGVycw=='); -@$core.Deprecated('Use queryRowPayloadDescriptor instead') -const QueryRowPayload$json = const { - '1': 'QueryRowPayload', +@$core.Deprecated('Use queryGridBlocksPayloadDescriptor instead') +const QueryGridBlocksPayload$json = const { + '1': 'QueryGridBlocksPayload', '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'row_orders', '3': 2, '4': 1, '5': 11, '6': '.RepeatedRowOrder', '10': 'rowOrders'}, + const {'1': 'blocks', '3': 2, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'}, ], }; -/// Descriptor for `QueryRowPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List queryRowPayloadDescriptor = $convert.base64Decode('Cg9RdWVyeVJvd1BheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEjAKCnJvd19vcmRlcnMYAiABKAsyES5SZXBlYXRlZFJvd09yZGVyUglyb3dPcmRlcnM='); +/// Descriptor for `QueryGridBlocksPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List queryGridBlocksPayloadDescriptor = $convert.base64Decode('ChZRdWVyeUdyaWRCbG9ja3NQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBImCgZibG9ja3MYAiADKAsyDi5HcmlkQmxvY2tNZXRhUgZibG9ja3M='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 38adc076a6..0a3cba6be6 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -17,7 +17,7 @@ class GridMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) - ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: GridBlock.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: GridBlockMeta.create) ..hasRequiredFields = false ; @@ -25,7 +25,7 @@ class GridMeta extends $pb.GeneratedMessage { factory GridMeta({ $core.String? gridId, $core.Iterable? fields, - $core.Iterable? blocks, + $core.Iterable? blocks, }) { final _result = create(); if (gridId != null) { @@ -73,102 +73,32 @@ class GridMeta extends $pb.GeneratedMessage { $core.List get fields => $_getList(1); @$pb.TagNumber(3) - $core.List get blocks => $_getList(2); -} - -class GridBlock extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startRowIndex', $pb.PbFieldType.O3) - ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowCount', $pb.PbFieldType.O3) - ..hasRequiredFields = false - ; - - GridBlock._() : super(); - factory GridBlock({ - $core.String? id, - $core.int? startRowIndex, - $core.int? rowCount, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (startRowIndex != null) { - _result.startRowIndex = startRowIndex; - } - if (rowCount != null) { - _result.rowCount = rowCount; - } - return _result; - } - factory GridBlock.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GridBlock.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - GridBlock clone() => GridBlock()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - GridBlock copyWith(void Function(GridBlock) updates) => super.copyWith((message) => updates(message as GridBlock)) as GridBlock; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static GridBlock create() => GridBlock._(); - GridBlock createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static GridBlock getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GridBlock? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get id => $_getSZ(0); - @$pb.TagNumber(1) - set id($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.int get startRowIndex => $_getIZ(1); - @$pb.TagNumber(2) - set startRowIndex($core.int v) { $_setSignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasStartRowIndex() => $_has(1); - @$pb.TagNumber(2) - void clearStartRowIndex() => clearField(2); - - @$pb.TagNumber(3) - $core.int get rowCount => $_getIZ(2); - @$pb.TagNumber(3) - set rowCount($core.int v) { $_setSignedInt32(2, v); } - @$pb.TagNumber(3) - $core.bool hasRowCount() => $_has(2); - @$pb.TagNumber(3) - void clearRowCount() => clearField(3); + $core.List get blocks => $_getList(2); } class GridBlockMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') - ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startRowIndex', $pb.PbFieldType.O3) + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowCount', $pb.PbFieldType.O3) ..hasRequiredFields = false ; GridBlockMeta._() : super(); factory GridBlockMeta({ $core.String? blockId, - $core.Iterable? rows, + $core.int? startRowIndex, + $core.int? rowCount, }) { final _result = create(); if (blockId != null) { _result.blockId = blockId; } - if (rows != null) { - _result.rows.addAll(rows); + if (startRowIndex != null) { + _result.startRowIndex = startRowIndex; + } + if (rowCount != null) { + _result.rowCount = rowCount; } return _result; } @@ -203,7 +133,77 @@ class GridBlockMeta extends $pb.GeneratedMessage { void clearBlockId() => clearField(1); @$pb.TagNumber(2) - $core.List get rows => $_getList(1); + $core.int get startRowIndex => $_getIZ(1); + @$pb.TagNumber(2) + set startRowIndex($core.int v) { $_setSignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasStartRowIndex() => $_has(1); + @$pb.TagNumber(2) + void clearStartRowIndex() => clearField(2); + + @$pb.TagNumber(3) + $core.int get rowCount => $_getIZ(2); + @$pb.TagNumber(3) + set rowCount($core.int v) { $_setSignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasRowCount() => $_has(2); + @$pb.TagNumber(3) + void clearRowCount() => clearField(3); +} + +class GridBlockMetaData extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMetaData', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowMetas', $pb.PbFieldType.PM, subBuilder: RowMeta.create) + ..hasRequiredFields = false + ; + + GridBlockMetaData._() : super(); + factory GridBlockMetaData({ + $core.String? blockId, + $core.Iterable? rowMetas, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + if (rowMetas != null) { + _result.rowMetas.addAll(rowMetas); + } + return _result; + } + factory GridBlockMetaData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlockMetaData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + GridBlockMetaData clone() => GridBlockMetaData()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridBlockMetaData copyWith(void Function(GridBlockMetaData) updates) => super.copyWith((message) => updates(message as GridBlockMetaData)) as GridBlockMetaData; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridBlockMetaData create() => GridBlockMetaData._(); + GridBlockMetaData createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridBlockMetaData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlockMetaData? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); + + @$pb.TagNumber(2) + $core.List get rowMetas => $_getList(1); } class FieldMeta extends $pb.GeneratedMessage { @@ -1020,16 +1020,16 @@ class CellMetaChangeset extends $pb.GeneratedMessage { class BuildGridContext extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BuildGridContext', createEmptyInstance: create) ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldMetas', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlock', subBuilder: GridBlock.create) - ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlockMeta', subBuilder: GridBlockMeta.create) + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlock', subBuilder: GridBlockMeta.create) + ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlockMetaData', subBuilder: GridBlockMetaData.create) ..hasRequiredFields = false ; BuildGridContext._() : super(); factory BuildGridContext({ $core.Iterable? fieldMetas, - GridBlock? gridBlock, - GridBlockMeta? gridBlockMeta, + GridBlockMeta? gridBlock, + GridBlockMetaData? gridBlockMetaData, }) { final _result = create(); if (fieldMetas != null) { @@ -1038,8 +1038,8 @@ class BuildGridContext extends $pb.GeneratedMessage { if (gridBlock != null) { _result.gridBlock = gridBlock; } - if (gridBlockMeta != null) { - _result.gridBlockMeta = gridBlockMeta; + if (gridBlockMetaData != null) { + _result.gridBlockMetaData = gridBlockMetaData; } return _result; } @@ -1068,25 +1068,25 @@ class BuildGridContext extends $pb.GeneratedMessage { $core.List get fieldMetas => $_getList(0); @$pb.TagNumber(2) - GridBlock get gridBlock => $_getN(1); + GridBlockMeta get gridBlock => $_getN(1); @$pb.TagNumber(2) - set gridBlock(GridBlock v) { setField(2, v); } + set gridBlock(GridBlockMeta v) { setField(2, v); } @$pb.TagNumber(2) $core.bool hasGridBlock() => $_has(1); @$pb.TagNumber(2) void clearGridBlock() => clearField(2); @$pb.TagNumber(2) - GridBlock ensureGridBlock() => $_ensure(1); + GridBlockMeta ensureGridBlock() => $_ensure(1); @$pb.TagNumber(3) - GridBlockMeta get gridBlockMeta => $_getN(2); + GridBlockMetaData get gridBlockMetaData => $_getN(2); @$pb.TagNumber(3) - set gridBlockMeta(GridBlockMeta v) { setField(3, v); } + set gridBlockMetaData(GridBlockMetaData v) { setField(3, v); } @$pb.TagNumber(3) - $core.bool hasGridBlockMeta() => $_has(2); + $core.bool hasGridBlockMetaData() => $_has(2); @$pb.TagNumber(3) - void clearGridBlockMeta() => clearField(3); + void clearGridBlockMetaData() => clearField(3); @$pb.TagNumber(3) - GridBlockMeta ensureGridBlockMeta() => $_ensure(2); + GridBlockMetaData ensureGridBlockMetaData() => $_ensure(2); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 7ce08c0a9d..7048fb3c81 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -29,35 +29,35 @@ const GridMeta$json = const { '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fields'}, - const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlock', '10': 'blocks'}, + const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'}, ], }; /// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSIgoGYmxvY2tzGAMgAygLMgouR3JpZEJsb2NrUgZibG9ja3M='); -@$core.Deprecated('Use gridBlockDescriptor instead') -const GridBlock$json = const { - '1': 'GridBlock', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'start_row_index', '3': 2, '4': 1, '5': 5, '10': 'startRowIndex'}, - const {'1': 'row_count', '3': 3, '4': 1, '5': 5, '10': 'rowCount'}, - ], -}; - -/// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSDgoCaWQYASABKAlSAmlkEiYKD3N0YXJ0X3Jvd19pbmRleBgCIAEoBVINc3RhcnRSb3dJbmRleBIbCglyb3dfY291bnQYAyABKAVSCHJvd0NvdW50'); +final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSJgoGYmxvY2tzGAMgAygLMg4uR3JpZEJsb2NrTWV0YVIGYmxvY2tz'); @$core.Deprecated('Use gridBlockMetaDescriptor instead') const GridBlockMeta$json = const { '1': 'GridBlockMeta', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'}, + const {'1': 'start_row_index', '3': 2, '4': 1, '5': 5, '10': 'startRowIndex'}, + const {'1': 'row_count', '3': 3, '4': 1, '5': 5, '10': 'rowCount'}, ], }; /// Descriptor for `GridBlockMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockMetaDescriptor = $convert.base64Decode('Cg1HcmlkQmxvY2tNZXRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEhwKBHJvd3MYAiADKAsyCC5Sb3dNZXRhUgRyb3dz'); +final $typed_data.Uint8List gridBlockMetaDescriptor = $convert.base64Decode('Cg1HcmlkQmxvY2tNZXRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEiYKD3N0YXJ0X3Jvd19pbmRleBgCIAEoBVINc3RhcnRSb3dJbmRleBIbCglyb3dfY291bnQYAyABKAVSCHJvd0NvdW50'); +@$core.Deprecated('Use gridBlockMetaDataDescriptor instead') +const GridBlockMetaData$json = const { + '1': 'GridBlockMetaData', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'row_metas', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rowMetas'}, + ], +}; + +/// Descriptor for `GridBlockMetaData`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockMetaDataDescriptor = $convert.base64Decode('ChFHcmlkQmxvY2tNZXRhRGF0YRIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIlCglyb3dfbWV0YXMYAiADKAsyCC5Sb3dNZXRhUghyb3dNZXRhcw=='); @$core.Deprecated('Use fieldMetaDescriptor instead') const FieldMeta$json = const { '1': 'FieldMeta', @@ -197,10 +197,10 @@ const BuildGridContext$json = const { '1': 'BuildGridContext', '2': const [ const {'1': 'field_metas', '3': 1, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fieldMetas'}, - const {'1': 'grid_block', '3': 2, '4': 1, '5': 11, '6': '.GridBlock', '10': 'gridBlock'}, - const {'1': 'grid_block_meta', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'gridBlockMeta'}, + const {'1': 'grid_block', '3': 2, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'gridBlock'}, + const {'1': 'grid_block_meta_data', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMetaData', '10': 'gridBlockMetaData'}, ], }; /// Descriptor for `BuildGridContext`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEikKCmdyaWRfYmxvY2sYAiABKAsyCi5HcmlkQmxvY2tSCWdyaWRCbG9jaxI2Cg9ncmlkX2Jsb2NrX21ldGEYAyABKAsyDi5HcmlkQmxvY2tNZXRhUg1ncmlkQmxvY2tNZXRh'); +final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEi0KCmdyaWRfYmxvY2sYAiABKAsyDi5HcmlkQmxvY2tNZXRhUglncmlkQmxvY2sSQwoUZ3JpZF9ibG9ja19tZXRhX2RhdGEYAyABKAsyEi5HcmlkQmxvY2tNZXRhRGF0YVIRZ3JpZEJsb2NrTWV0YURhdGE='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart index 9f4245122f..54f33ea020 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart @@ -11,17 +11,13 @@ import 'package:protobuf/protobuf.dart' as $pb; class GridNotification extends $pb.ProtobufEnum { static const GridNotification Unknown = GridNotification._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown'); - static const GridNotification GridDidCreateRows = GridNotification._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidCreateRows'); - static const GridNotification GridDidDeleteRow = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidDeleteRow'); - static const GridNotification GridDidUpdateRows = GridNotification._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateRows'); + static const GridNotification GridDidUpdateBlock = GridNotification._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateBlock'); static const GridNotification GridDidUpdateCells = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateCells'); static const GridNotification GridDidUpdateFields = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateFields'); static const $core.List values = [ Unknown, - GridDidCreateRows, - GridDidDeleteRow, - GridDidUpdateRows, + GridDidUpdateBlock, GridDidUpdateCells, GridDidUpdateFields, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart index 5100550835..4c4ff69eb1 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart @@ -13,13 +13,11 @@ const GridNotification$json = const { '1': 'GridNotification', '2': const [ const {'1': 'Unknown', '2': 0}, - const {'1': 'GridDidCreateRows', '2': 10}, - const {'1': 'GridDidDeleteRow', '2': 11}, - const {'1': 'GridDidUpdateRows', '2': 12}, + const {'1': 'GridDidUpdateBlock', '2': 10}, const {'1': 'GridDidUpdateCells', '2': 20}, const {'1': 'GridDidUpdateFields', '2': 30}, ], }; /// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIVChFHcmlkRGlkQ3JlYXRlUm93cxAKEhQKEEdyaWREaWREZWxldGVSb3cQCxIVChFHcmlkRGlkVXBkYXRlUm93cxAMEhYKEkdyaWREaWRVcGRhdGVDZWxscxAUEhcKE0dyaWREaWRVcGRhdGVGaWVsZHMQHg=='); +final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIWChJHcmlkRGlkVXBkYXRlQmxvY2sQChIWChJHcmlkRGlkVXBkYXRlQ2VsbHMQFBIXChNHcmlkRGlkVXBkYXRlRmllbGRzEB4='); 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 ac47fe4a51..787f44e52c 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 @@ -11,14 +11,14 @@ import 'package:protobuf/protobuf.dart' as $pb; class GridEvent extends $pb.ProtobufEnum { static const GridEvent GetGridData = GridEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetGridData'); - static const GridEvent GetRows = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRows'); + static const GridEvent GetGridBlocks = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetGridBlocks'); static const GridEvent GetFields = GridEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields'); static const GridEvent CreateRow = GridEvent._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const GridEvent UpdateCell = GridEvent._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); static const $core.List values = [ GetGridData, - GetRows, + GetGridBlocks, GetFields, CreateRow, UpdateCell, 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 145521943a..707eca7c61 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 @@ -13,7 +13,7 @@ const GridEvent$json = const { '1': 'GridEvent', '2': const [ const {'1': 'GetGridData', '2': 0}, - const {'1': 'GetRows', '2': 1}, + const {'1': 'GetGridBlocks', '2': 1}, const {'1': 'GetFields', '2': 2}, const {'1': 'CreateRow', '2': 3}, const {'1': 'UpdateCell', '2': 4}, @@ -21,4 +21,4 @@ const GridEvent$json = const { }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABILCgdHZXRSb3dzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAMSDgoKVXBkYXRlQ2VsbBAE'); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAMSDgoKVXBkYXRlQ2VsbBAE'); diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs index d6fb15d719..ba0396bf7f 100644 --- a/frontend/rust-lib/flowy-grid/src/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -5,9 +5,7 @@ const OBSERVABLE_CATEGORY: &str = "Grid"; #[derive(ProtoBuf_Enum, Debug)] pub enum GridNotification { Unknown = 0, - GridDidCreateRows = 10, - GridDidDeleteRow = 11, - GridDidUpdateRows = 12, + GridDidUpdateBlock = 10, GridDidUpdateCells = 20, GridDidUpdateFields = 30, diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 9d0001305d..8921d15aea 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,8 +1,8 @@ use crate::manager::GridManager; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ - CellMetaChangeset, CreateRowPayload, Field, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, - RepeatedRow, Row, + CellMetaChangeset, CreateRowPayload, Field, Grid, GridId, QueryFieldPayload, QueryGridBlocksPayload, RepeatedField, + RepeatedGridBlock, Row, }; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -19,14 +19,14 @@ pub(crate) async fn get_grid_data_handler( } #[tracing::instrument(level = "debug", skip(data, manager), err)] -pub(crate) async fn get_rows_handler( - data: Data, +pub(crate) async fn get_grid_blocks_handler( + data: Data, manager: AppData>, -) -> DataResult { - let payload: QueryRowPayload = data.into_inner(); +) -> DataResult { + let payload: QueryGridBlocksPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_row: RepeatedRow = editor.get_rows(Some(payload.row_orders)).await?.into(); - data_result(repeated_row) + let repeated_grid_block = editor.get_grid_blocks(Some(payload.blocks)).await?; + data_result(repeated_grid_block) } #[tracing::instrument(level = "debug", skip(data, manager), err)] diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 6adc06e709..d748b3b882 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -9,7 +9,7 @@ pub fn create(grid_manager: Arc) -> Module { let mut module = Module::new().name(env!("CARGO_PKG_NAME")).data(grid_manager); module = module .event(GridEvent::GetGridData, get_grid_data_handler) - .event(GridEvent::GetRows, get_rows_handler) + .event(GridEvent::GetGridBlocks, get_grid_blocks_handler) .event(GridEvent::GetFields, get_fields_handler) .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::UpdateCell, update_cell_handler); @@ -23,8 +23,8 @@ pub enum GridEvent { #[event(input = "GridId", output = "Grid")] GetGridData = 0, - #[event(input = "QueryRowPayload", output = "RepeatedRow")] - GetRows = 1, + #[event(input = "QueryGridBlocksPayload", output = "RepeatedGridBlock")] + GetGridBlocks = 1, #[event(input = "QueryFieldPayload", output = "RepeatedField")] GetFields = 2, diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index fde6d136f2..7afcdf05fd 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -182,7 +182,7 @@ pub async fn make_grid_view_data( grid_manager: Arc, build_context: BuildGridContext, ) -> FlowyResult { - let block_id = build_context.grid_block.id.clone(); + let block_id = build_context.grid_block.block_id.clone(); let grid_meta = GridMeta { grid_id: view_id.to_string(), fields: build_context.field_metas, @@ -195,7 +195,7 @@ pub async fn make_grid_view_data( Revision::initial_revision(user_id, view_id, grid_delta_data.clone()).into(); let _ = grid_manager.create_grid(view_id, repeated_revision).await?; - let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta); + let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta_data); let block_meta_delta_data = grid_block_meta_delta.to_delta_bytes(); let repeated_revision: RepeatedRevision = Revision::initial_revision(user_id, &block_id, block_meta_delta_data).into(); diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs index 63676bd6e6..a4f7fbb46c 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs @@ -26,9 +26,7 @@ #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum GridNotification { Unknown = 0, - GridDidCreateRows = 10, - GridDidDeleteRow = 11, - GridDidUpdateRows = 12, + GridDidUpdateBlock = 10, GridDidUpdateCells = 20, GridDidUpdateFields = 30, } @@ -41,9 +39,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { fn from_i32(value: i32) -> ::std::option::Option { match value { 0 => ::std::option::Option::Some(GridNotification::Unknown), - 10 => ::std::option::Option::Some(GridNotification::GridDidCreateRows), - 11 => ::std::option::Option::Some(GridNotification::GridDidDeleteRow), - 12 => ::std::option::Option::Some(GridNotification::GridDidUpdateRows), + 10 => ::std::option::Option::Some(GridNotification::GridDidUpdateBlock), 20 => ::std::option::Option::Some(GridNotification::GridDidUpdateCells), 30 => ::std::option::Option::Some(GridNotification::GridDidUpdateFields), _ => ::std::option::Option::None @@ -53,9 +49,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { fn values() -> &'static [Self] { static values: &'static [GridNotification] = &[ GridNotification::Unknown, - GridNotification::GridDidCreateRows, - GridNotification::GridDidDeleteRow, - GridNotification::GridDidUpdateRows, + GridNotification::GridDidUpdateBlock, GridNotification::GridDidUpdateCells, GridNotification::GridDidUpdateFields, ]; @@ -86,11 +80,9 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x17dart_notification.proto*\x94\x01\n\x10GridNotification\x12\x0b\n\ - \x07Unknown\x10\0\x12\x15\n\x11GridDidCreateRows\x10\n\x12\x14\n\x10Grid\ - DidDeleteRow\x10\x0b\x12\x15\n\x11GridDidUpdateRows\x10\x0c\x12\x16\n\ - \x12GridDidUpdateCells\x10\x14\x12\x17\n\x13GridDidUpdateFields\x10\x1eb\ - \x06proto3\ + \n\x17dart_notification.proto*h\n\x10GridNotification\x12\x0b\n\x07Unkno\ + wn\x10\0\x12\x16\n\x12GridDidUpdateBlock\x10\n\x12\x16\n\x12GridDidUpdat\ + eCells\x10\x14\x12\x17\n\x13GridDidUpdateFields\x10\x1eb\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/model/event_map.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs index 028f37bab5..1ed38366d4 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 @@ -26,7 +26,7 @@ #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum GridEvent { GetGridData = 0, - GetRows = 1, + GetGridBlocks = 1, GetFields = 2, CreateRow = 3, UpdateCell = 4, @@ -40,7 +40,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { fn from_i32(value: i32) -> ::std::option::Option { match value { 0 => ::std::option::Option::Some(GridEvent::GetGridData), - 1 => ::std::option::Option::Some(GridEvent::GetRows), + 1 => ::std::option::Option::Some(GridEvent::GetGridBlocks), 2 => ::std::option::Option::Some(GridEvent::GetFields), 3 => ::std::option::Option::Some(GridEvent::CreateRow), 4 => ::std::option::Option::Some(GridEvent::UpdateCell), @@ -51,7 +51,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { fn values() -> &'static [Self] { static values: &'static [GridEvent] = &[ GridEvent::GetGridData, - GridEvent::GetRows, + GridEvent::GetGridBlocks, GridEvent::GetFields, GridEvent::CreateRow, GridEvent::UpdateCell, @@ -83,9 +83,9 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*W\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\ - \x0b\n\x07GetRows\x10\x01\x12\r\n\tGetFields\x10\x02\x12\r\n\tCreateRow\ - \x10\x03\x12\x0e\n\nUpdateCell\x10\x04b\x06proto3\ + \n\x0fevent_map.proto*]\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\ + \x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\x02\x12\r\n\tCreate\ + Row\x10\x03\x12\x0e\n\nUpdateCell\x10\x04b\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/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto index 9c606ac091..9aadc14372 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto @@ -2,9 +2,7 @@ syntax = "proto3"; enum GridNotification { Unknown = 0; - GridDidCreateRows = 10; - GridDidDeleteRow = 11; - GridDidUpdateRows = 12; + GridDidUpdateBlock = 10; GridDidUpdateCells = 20; GridDidUpdateFields = 30; } 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 e06c2e56b3..a5c998e7e1 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 @@ -2,7 +2,7 @@ syntax = "proto3"; enum GridEvent { GetGridData = 0; - GetRows = 1; + GetGridBlocks = 1; GetFields = 2; CreateRow = 3; UpdateCell = 4; 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 8e49a47588..21046c295c 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 @@ -1,14 +1,14 @@ use crate::manager::GridUser; -use crate::services::row::{make_cell, make_row_ids_per_block, make_rows}; +use crate::services::row::{make_cell, make_grid_blocks, make_row_ids_per_block, GridBlockMetaDataSnapshot}; use bytes::Bytes; use dashmap::DashMap; -use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; +use flowy_collaboration::client_grid::{GridBlockMetaDataChange, GridBlockMetaDataPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Cell, FieldMeta, GridBlock, GridBlockChangeset, RepeatedCell, RepeatedRow, RepeatedRowOrder, RowMeta, + Cell, FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, RepeatedCell, RepeatedRowOrder, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; @@ -30,12 +30,12 @@ type BlockId = String; pub(crate) struct GridBlockMetaEditorManager { grid_id: String, user: Arc, - editor_map: DashMap>, + editor_map: DashMap>, block_id_by_row_id: DashMap, } impl GridBlockMetaEditorManager { - pub(crate) async fn new(grid_id: &str, user: &Arc, blocks: Vec) -> FlowyResult { + pub(crate) async fn new(grid_id: &str, user: &Arc, blocks: Vec) -> FlowyResult { let editor_map = make_block_meta_editor_map(user, blocks).await?; let user = user.clone(); let block_id_by_row_id = DashMap::new(); @@ -49,7 +49,7 @@ impl GridBlockMetaEditorManager { Ok(manager) } - pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult> { + pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult> { match self.editor_map.get(block_id) { None => { tracing::error!("The is a fatal error, block is not exist"); @@ -63,29 +63,22 @@ impl GridBlockMetaEditorManager { pub(crate) async fn create_row( &self, - field_metas: &[FieldMeta], + block_id: &str, row_meta: RowMeta, - upper_row_id: Option, + start_row_id: Option, ) -> FlowyResult { self.block_id_by_row_id .insert(row_meta.id.clone(), row_meta.block_id.clone()); let editor = self.get_editor(&row_meta.block_id).await?; - - let rows = make_rows(field_metas, vec![row_meta.clone().into()]); - send_dart_notification(&self.grid_id, GridNotification::GridDidCreateRows) - .payload(RepeatedRow::from(rows)) - .send(); - - self.notify_did_create_rows(field_metas, vec![row_meta.clone()]); - - editor.create_row(row_meta, upper_row_id).await + let row_count = editor.create_row(row_meta, start_row_id).await?; + self.notify_did_update_block(block_id).await?; + Ok(row_count) } pub(crate) async fn insert_row( &self, - field_metas: &[FieldMeta], rows_by_block_id: HashMap>, - ) -> FlowyResult> { + ) -> FlowyResult> { let mut changesets = vec![]; for (block_id, row_metas) in rows_by_block_id { let editor = self.get_editor(&block_id).await?; @@ -94,14 +87,14 @@ impl GridBlockMetaEditorManager { self.block_id_by_row_id.insert(row.id.clone(), row.block_id.clone()); row_count = editor.create_row(row.clone(), None).await?; } - changesets.push(GridBlockChangeset::from_row_count(&block_id, row_count)); - self.notify_did_create_rows(field_metas, row_metas); + changesets.push(GridBlockMetaChangeset::from_row_count(&block_id, row_count)); + let _ = self.notify_did_update_block(&block_id).await?; } Ok(changesets) } - pub(crate) async fn delete_rows(&self, row_ids: Vec) -> FlowyResult> { + pub(crate) async fn delete_rows(&self, row_ids: Vec) -> FlowyResult> { let row_orders = row_ids .into_iter() .flat_map(|row_id| { @@ -117,7 +110,7 @@ impl GridBlockMetaEditorManager { let editor = self.get_editor(&row_ids_per_block.block_id).await?; let row_count = editor.delete_rows(row_ids_per_block.row_ids).await?; - let changeset = GridBlockChangeset::from_row_count(&row_ids_per_block.block_id, row_count); + let changeset = GridBlockMetaChangeset::from_row_count(&row_ids_per_block.block_id, row_count); changesets.push(changeset); } @@ -127,7 +120,7 @@ impl GridBlockMetaEditorManager { pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { let editor = self.get_editor_from_row_id(&changeset.row_id).await?; let _ = editor.update_row(changeset.clone()).await?; - let _ = self.notify_did_update_row()?; + let _ = self.notify_did_update_block(&editor.block_id).await?; Ok(()) } @@ -138,48 +131,58 @@ impl GridBlockMetaEditorManager { Ok(()) } - pub(crate) async fn get_all_rows(&self, grid_blocks: Vec) -> FlowyResult>> { - let mut row_metas = vec![]; + pub(crate) async fn get_block_meta_snapshot_from_blocks( + &self, + grid_blocks: Vec, + ) -> FlowyResult> { + let mut snapshots = vec![]; for grid_block in grid_blocks { - let editor = self.get_editor(&grid_block.id).await?; - let new_row_metas = editor.get_row_metas(None).await?; - new_row_metas.iter().for_each(|row_meta| { + let editor = self.get_editor(&grid_block.block_id).await?; + let row_metas = editor.get_row_metas(None).await?; + row_metas.iter().for_each(|row_meta| { self.block_id_by_row_id .insert(row_meta.id.clone(), row_meta.block_id.clone()); }); - row_metas.extend(new_row_metas); + snapshots.push(GridBlockMetaDataSnapshot { + block_id: grid_block.block_id, + row_metas, + }); } - Ok(row_metas) + Ok(snapshots) } - pub(crate) async fn get_row_orders(&self, grid_blocks: Vec) -> FlowyResult> { - let mut row_orders = vec![]; - for grid_block in grid_blocks { - let editor = self.get_editor(&grid_block.id).await?; + pub(crate) async fn get_block_meta_snapshot_from_row_orders( + &self, + grid_block_metas: &Vec, + ) -> FlowyResult> { + let mut snapshots = vec![]; + for grid_block_meta in grid_block_metas { + let editor = self.get_editor(&grid_block_meta.block_id).await?; let row_metas = editor.get_row_metas(None).await?; - let block_row_orders = row_metas.iter().map(RowOrder::from); - row_orders.extend(block_row_orders); + row_metas.iter().for_each(|row_meta| { + self.block_id_by_row_id + .insert(row_meta.id.clone(), row_meta.block_id.clone()); + }); + snapshots.push(GridBlockMetaDataSnapshot { + block_id: grid_block_meta.block_id.clone(), + row_metas, + }); + } + Ok(snapshots) + } + + pub(crate) async fn get_row_orders(&self, grid_block_ids: Vec) -> FlowyResult> { + let mut row_orders = vec![]; + for grid_block_id in grid_block_ids { + let editor = self.get_editor(&grid_block_id).await?; + let new_row_order = editor.get_row_orders().await?; + row_orders.extend(new_row_order); } Ok(row_orders) } - pub(crate) async fn get_rows(&self, row_orders: &RepeatedRowOrder) -> FlowyResult>> { - let row_ids_per_blocks = make_row_ids_per_block(row_orders); - let mut row_metas = vec![]; - for row_ids_per_block in row_ids_per_blocks { - let editor = self.get_editor(&row_ids_per_block.block_id).await?; - let new_row_metas = editor.get_row_metas(Some(row_ids_per_block.row_ids)).await?; - new_row_metas.iter().for_each(|row_meta| { - self.block_id_by_row_id - .insert(row_meta.id.clone(), row_meta.block_id.clone()); - }); - row_metas.extend(new_row_metas); - } - Ok(row_metas) - } - - async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { + async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { match self.block_id_by_row_id.get(row_id) { None => { let msg = format!( @@ -195,25 +198,14 @@ impl GridBlockMetaEditorManager { } } - fn notify_did_create_rows(&self, field_metas: &[FieldMeta], row_metas: Vec) { - let rows = make_rows( - field_metas, - row_metas - .into_iter() - .map(|row_meta| Arc::new(row_meta)) - .collect::>(), - ); - send_dart_notification(&self.grid_id, GridNotification::GridDidCreateRows) - .payload(RepeatedRow::from(rows)) + async fn notify_did_update_block(&self, block_id: &str) -> FlowyResult<()> { + let block_id = GridBlockId { + value: block_id.to_owned(), + }; + send_dart_notification(&self.grid_id, GridNotification::GridDidUpdateBlock) + .payload(block_id) .send(); - } - - fn notify_did_update_row(&self) -> FlowyResult<()> { - // send_dart_notification(&changeset.row_id, GridNotification::GridDidUpdateRows) - // .payload(RepeatedRow::from(cells)) - // .send(); - - todo!() + Ok(()) } fn notify_did_update_cells(&self, changeset: RowMetaChangeset, field_metas: &[FieldMeta]) -> FlowyResult<()> { @@ -244,18 +236,21 @@ impl GridBlockMetaEditorManager { async fn make_block_meta_editor_map( user: &Arc, - blocks: Vec, -) -> FlowyResult>> { + blocks: Vec, +) -> FlowyResult>> { let editor_map = DashMap::new(); for block in blocks { - let editor = make_block_meta_editor(user, &block.id).await?; - editor_map.insert(block.id, Arc::new(editor)); + let editor = make_block_meta_editor(user, &block.block_id).await?; + editor_map.insert(block.block_id, Arc::new(editor)); } 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()?; @@ -263,17 +258,17 @@ 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 + ClientGridBlockMetaDataEditor::new(&user_id, &token, block_id, rev_manager).await } -pub struct ClientGridBlockMetaEditor { +pub struct ClientGridBlockMetaDataEditor { user_id: String, pub block_id: String, - meta_pad: Arc>, + pad: Arc>, rev_manager: Arc, } -impl ClientGridBlockMetaEditor { +impl ClientGridBlockMetaDataEditor { pub async fn new( user_id: &str, token: &str, @@ -284,23 +279,23 @@ impl ClientGridBlockMetaEditor { token: token.to_owned(), }); let block_meta_pad = rev_manager.load::(Some(cloud)).await?; - let meta_pad = Arc::new(RwLock::new(block_meta_pad)); + let pad = Arc::new(RwLock::new(block_meta_pad)); let rev_manager = Arc::new(rev_manager); let user_id = user_id.to_owned(); let block_id = block_id.to_owned(); Ok(Self { user_id, block_id, - meta_pad, + pad, rev_manager, }) } - async fn create_row(&self, row: RowMeta, upper_row_id: Option) -> FlowyResult { + async fn create_row(&self, row: RowMeta, start_row_id: Option) -> FlowyResult { let mut row_count = 0; let _ = self .modify(|pad| { - let change = pad.add_row(row, upper_row_id)?; + let change = pad.add_row(row, start_row_id)?; row_count = pad.number_of_rows(); Ok(change) }) @@ -327,13 +322,13 @@ impl ClientGridBlockMetaEditor { } pub async fn get_row_metas(&self, row_ids: Option>) -> FlowyResult>> { - let row_metas = self.meta_pad.read().await.get_rows(row_ids)?; + let row_metas = self.pad.read().await.get_rows(row_ids)?; Ok(row_metas) } pub async fn get_row_orders(&self) -> FlowyResult> { let row_orders = self - .meta_pad + .pad .read() .await .get_rows(None)? @@ -345,9 +340,9 @@ impl ClientGridBlockMetaEditor { async fn modify(&self, f: F) -> FlowyResult<()> where - F: for<'a> FnOnce(&'a mut GridBlockMetaPad) -> FlowyResult>, + F: for<'a> FnOnce(&'a mut GridBlockMetaDataPad) -> FlowyResult>, { - let mut write_guard = self.meta_pad.write().await; + let mut write_guard = self.pad.write().await; match f(&mut *write_guard)? { None => {} Some(change) => { @@ -357,8 +352,8 @@ impl ClientGridBlockMetaEditor { Ok(()) } - async fn apply_change(&self, change: GridBlockMetaChange) -> FlowyResult<()> { - let GridBlockMetaChange { delta, md5 } = change; + async fn apply_change(&self, change: GridBlockMetaDataChange) -> FlowyResult<()> { + let GridBlockMetaDataChange { delta, md5 } = change; let user_id = self.user_id.clone(); let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); let delta_data = delta.to_delta_bytes(); @@ -392,10 +387,10 @@ impl RevisionCloudService for GridBlockMetaRevisionCloudService { struct GridBlockMetaPadBuilder(); impl RevisionObjectBuilder for GridBlockMetaPadBuilder { - type Output = GridBlockMetaPad; + type Output = GridBlockMetaDataPad; fn build_object(object_id: &str, revisions: Vec) -> FlowyResult { - let pad = GridBlockMetaPad::from_revisions(object_id, revisions)?; + let pad = GridBlockMetaDataPad::from_revisions(object_id, revisions)?; Ok(pad) } } 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 491a2831bb..f991d26a10 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -6,14 +6,15 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Cell, CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlock, GridBlockChangeset, RepeatedField, - RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, + Cell, CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlockMeta, GridBlockMetaChangeset, + RepeatedField, RepeatedFieldOrder, RepeatedGridBlock, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, }; use std::collections::HashMap; use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::services::row::{ - make_row_by_row_id, make_rows, row_meta_from_context, serialize_cell_data, RowMetaContext, RowMetaContextBuilder, + make_grid_block_from_block_metas, make_grid_blocks, make_row_ids_per_block, row_meta_from_context, + serialize_cell_data, GridBlockMetaDataSnapshot, RowMetaContext, RowMetaContextBuilder, }; use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; @@ -24,7 +25,7 @@ use tokio::sync::RwLock; pub struct ClientGridEditor { grid_id: String, user: Arc, - grid_meta_pad: Arc>, + pad: Arc>, rev_manager: Arc, block_meta_manager: Arc, } @@ -39,16 +40,15 @@ impl ClientGridEditor { let cloud = Arc::new(GridRevisionCloudService { token }); let grid_pad = rev_manager.load::(Some(cloud)).await?; let rev_manager = Arc::new(rev_manager); - let grid_meta_pad = Arc::new(RwLock::new(grid_pad)); + let pad = Arc::new(RwLock::new(grid_pad)); - let block_meta_manager = Arc::new( - GridBlockMetaEditorManager::new(grid_id, &user, grid_meta_pad.read().await.get_blocks().clone()).await?, - ); + let block_meta_manager = + Arc::new(GridBlockMetaEditorManager::new(grid_id, &user, pad.read().await.get_blocks().clone()).await?); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), user, - grid_meta_pad, + pad, rev_manager, block_meta_manager, })) @@ -61,7 +61,7 @@ impl ClientGridEditor { } pub async fn contain_field(&self, field_meta: &FieldMeta) -> bool { - self.grid_meta_pad.read().await.contain_field(&field_meta.id) + self.pad.read().await.contain_field(&field_meta.id) } pub async fn update_field(&self, change: FieldChangeset) -> FlowyResult<()> { @@ -74,19 +74,19 @@ impl ClientGridEditor { Ok(()) } - pub async fn create_block(&self, grid_block: GridBlock) -> FlowyResult<()> { + pub async fn create_block(&self, grid_block: GridBlockMeta) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.create_block(grid_block)?)).await?; Ok(()) } - pub async fn update_block(&self, changeset: GridBlockChangeset) -> FlowyResult<()> { + pub async fn update_block(&self, changeset: GridBlockMetaChangeset) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.update_block(changeset)?)).await?; Ok(()) } - pub async fn create_row(&self, upper_row_id: Option) -> FlowyResult<()> { - let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?; - let block_id = self.last_block_id().await?; + pub async fn create_row(&self, start_row_id: Option) -> FlowyResult<()> { + let field_metas = self.pad.read().await.get_field_metas(None)?; + let block_id = self.block_id().await?; // insert empty row below the row whose id is upper_row_id let row_meta_ctx = RowMetaContextBuilder::new(&field_metas).build(); @@ -95,18 +95,17 @@ impl ClientGridEditor { // insert the row let row_count = self .block_meta_manager - .create_row(&field_metas, row_meta, upper_row_id) + .create_row(&block_id, row_meta, start_row_id) .await?; // update block row count - let changeset = GridBlockChangeset::from_row_count(&block_id, row_count); + let changeset = GridBlockMetaChangeset::from_row_count(&block_id, row_count); let _ = self.update_block(changeset).await?; Ok(()) } pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult<()> { - let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?; - let block_id = self.last_block_id().await?; + let block_id = self.block_id().await?; let mut rows_by_block_id: HashMap> = HashMap::new(); for ctx in contexts { let row_meta = row_meta_from_context(&block_id, ctx); @@ -115,10 +114,7 @@ impl ClientGridEditor { .or_insert_with(Vec::new) .push(row_meta); } - let changesets = self - .block_meta_manager - .insert_row(&field_metas, rows_by_block_id) - .await?; + let changesets = self.block_meta_manager.insert_row(rows_by_block_id).await?; for changeset in changesets { let _ = self.update_block(changeset).await?; } @@ -131,7 +127,7 @@ impl ClientGridEditor { pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> { if let Some(cell_data) = changeset.data.as_ref() { - match self.grid_meta_pad.read().await.get_field(&changeset.field_id) { + match self.pad.read().await.get_field(&changeset.field_id) { None => { return Err(FlowyError::internal() .context(format!("Can not find the field with id: {}", &changeset.field_id))); @@ -151,32 +147,39 @@ impl ClientGridEditor { Ok(()) } - pub async fn get_rows(&self, row_orders: Option) -> FlowyResult> { - let row_metas = self.get_row_metas(row_orders.as_ref()).await?; - let field_meta = self.grid_meta_pad.read().await.get_field_metas(None)?; - match row_orders { - None => Ok(make_rows(&field_meta, row_metas)), - Some(row_orders) => { - let mut row_map: HashMap = make_row_by_row_id(&field_meta, row_metas); - let rows = row_orders - .iter() - .flat_map(|row_order| row_map.remove(&row_order.row_id)) - .collect::>(); - Ok(rows) + pub async fn get_grid_blocks( + &self, + grid_block_metas: Option>, + ) -> FlowyResult { + let grid_block_meta_snapshots = self.get_grid_block_meta_snapshots(grid_block_metas.as_ref()).await?; + let field_meta = self.pad.read().await.get_field_metas(None)?; + match grid_block_metas { + None => make_grid_blocks(&field_meta, grid_block_meta_snapshots), + Some(grid_block_metas) => { + make_grid_block_from_block_metas(&field_meta, grid_block_metas, grid_block_meta_snapshots) } } } - pub async fn get_row_metas(&self, row_orders: Option<&RepeatedRowOrder>) -> FlowyResult>> { - match row_orders { + pub(crate) async fn get_grid_block_meta_snapshots( + &self, + grid_block_infos: Option<&Vec>, + ) -> FlowyResult> { + match grid_block_infos { None => { - let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); - let row_metas = self.block_meta_manager.get_all_rows(grid_blocks).await?; - Ok(row_metas) + let grid_blocks = self.pad.read().await.get_blocks(); + let row_metas_per_block = self + .block_meta_manager + .get_block_meta_snapshot_from_blocks(grid_blocks) + .await?; + Ok(row_metas_per_block) } - Some(row_orders) => { - let row_metas = self.block_meta_manager.get_rows(row_orders).await?; - Ok(row_metas) + Some(grid_block_infos) => { + let row_metas_per_block = self + .block_meta_manager + .get_block_meta_snapshot_from_row_orders(grid_block_infos) + .await?; + Ok(row_metas_per_block) } } } @@ -190,35 +193,34 @@ impl ClientGridEditor { } pub async fn grid_data(&self) -> FlowyResult { - let field_orders = self.grid_meta_pad.read().await.get_field_orders(); - let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); - let row_orders = self.block_meta_manager.get_row_orders(grid_blocks).await?; + let field_orders = self.pad.read().await.get_field_orders(); + let block_orders = self.pad.read().await.get_blocks(); Ok(Grid { id: self.grid_id.clone(), field_orders, - row_orders, + blocks: block_orders, }) } pub async fn get_field_metas(&self, field_orders: Option) -> FlowyResult> { - let field_meta = self.grid_meta_pad.read().await.get_field_metas(field_orders)?; + let field_meta = self.pad.read().await.get_field_metas(field_orders)?; Ok(field_meta) } - pub async fn get_blocks(&self) -> FlowyResult> { - let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); + pub async fn get_blocks(&self) -> FlowyResult> { + let grid_blocks = self.pad.read().await.get_blocks(); Ok(grid_blocks) } pub async fn delta_bytes(&self) -> Bytes { - self.grid_meta_pad.read().await.delta_bytes() + self.pad.read().await.delta_bytes() } async fn modify(&self, f: F) -> FlowyResult<()> where F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult>, { - let mut write_guard = self.grid_meta_pad.write().await; + let mut write_guard = self.pad.write().await; match f(&mut *write_guard)? { None => {} Some(change) => { @@ -248,10 +250,10 @@ impl ClientGridEditor { Ok(()) } - async fn last_block_id(&self) -> FlowyResult { - match self.grid_meta_pad.read().await.get_blocks().last() { + async fn block_id(&self) -> FlowyResult { + match self.pad.read().await.get_blocks().last() { None => Err(FlowyError::internal().context("There is no grid block in this grid")), - Some(grid_block) => Ok(grid_block.id.clone()), + Some(grid_block) => Ok(grid_block.block_id.clone()), } } 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 6283db0540..953a950917 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 @@ -1,5 +1,8 @@ use crate::services::row::deserialize_cell_data; -use flowy_grid_data_model::entities::{Cell, CellMeta, FieldMeta, Row, RowMeta, RowOrder}; +use flowy_error::FlowyResult; +use flowy_grid_data_model::entities::{ + Cell, CellMeta, FieldMeta, GridBlock, GridBlockMeta, RepeatedGridBlock, RepeatedRowOrder, Row, RowMeta, RowOrder, +}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; use std::ops::Deref; @@ -10,41 +13,48 @@ pub(crate) struct RowIdsPerBlock { pub(crate) row_ids: Vec, } -pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec { - let mut map: HashMap = HashMap::new(); - row_orders.iter().for_each(|row_order| { - let block_id = row_order.block_id.clone(); - let entry = map.entry(block_id.clone()).or_insert(RowIdsPerBlock { - block_id, +impl RowIdsPerBlock { + pub fn new(block_id: &str) -> Self { + RowIdsPerBlock { + block_id: block_id.to_owned(), row_ids: vec![], - }); - entry.row_ids.push(row_order.row_id.clone()); + } + } +} + +pub(crate) struct GridBlockMetaDataSnapshot { + pub(crate) block_id: String, + pub(crate) row_metas: Vec>, +} + +pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec { + let mut map: HashMap<&String, RowIdsPerBlock> = HashMap::new(); + row_orders.iter().for_each(|row_order| { + let block_id = &row_order.block_id; + let row_id = row_order.row_id.clone(); + map.entry(&block_id) + .or_insert_with(|| RowIdsPerBlock::new(&block_id)) + .row_ids + .push(row_id); }); map.into_values().collect::>() } -pub(crate) fn make_rows(fields: &[FieldMeta], row_metas: Vec>) -> Vec { - let field_map = fields - .iter() - .map(|field| (&field.id, field)) - .collect::>(); - - let make_row = |row_meta: Arc| { - let cell_by_field_id = row_meta - .cell_by_field_id - .clone() - .into_par_iter() - .flat_map(|(field_id, raw_cell)| make_cell(&field_map, field_id, raw_cell)) - .collect::>(); - - Row { - id: row_meta.id.clone(), - cell_by_field_id, - height: row_meta.height, - } - }; - - row_metas.into_iter().map(make_row).collect::>() +pub(crate) fn make_grid_blocks( + field_metas: &[FieldMeta], + grid_block_meta_snapshots: Vec, +) -> FlowyResult { + Ok(grid_block_meta_snapshots + .into_iter() + .map(|row_metas_per_block| { + let rows = make_rows_from_row_metas(field_metas, &row_metas_per_block.row_metas); + GridBlock { + block_id: row_metas_per_block.block_id, + rows, + } + }) + .collect::>() + .into()) } #[inline(always)] @@ -66,13 +76,13 @@ pub fn make_cell( } } -pub(crate) fn make_row_by_row_id(fields: &[FieldMeta], row_metas: Vec>) -> HashMap { +pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &Vec>) -> Vec { let field_meta_map = fields .iter() .map(|field_meta| (&field_meta.id, field_meta)) .collect::>(); - let make_row = |row_meta: Arc| { + let make_row = |row_meta: &Arc| { let cell_by_field_id = row_meta .cell_by_field_id .clone() @@ -80,16 +90,36 @@ pub(crate) fn make_row_by_row_id(fields: &[FieldMeta], row_metas: Vec>(); - let row = Row { + Row { id: row_meta.id.clone(), cell_by_field_id, height: row_meta.height, - }; - (row.id.clone(), row) + } }; - row_metas - .into_par_iter() - .map(make_row) - .collect::>() + row_metas.into_iter().map(make_row).collect::>() +} + +pub(crate) fn make_grid_block_from_block_metas( + field_metas: &[FieldMeta], + grid_block_metas: Vec, + grid_block_meta_snapshots: Vec, +) -> FlowyResult { + let block_meta_snapshot_map: HashMap<&String, &Vec>> = grid_block_meta_snapshots + .iter() + .map(|snapshot| (&snapshot.block_id, &snapshot.row_metas)) + .collect(); + + let mut grid_blocks = vec![]; + for grid_block_meta in grid_block_metas { + match block_meta_snapshot_map.get(&grid_block_meta.block_id) { + None => {} + Some(row_metas) => { + let rows = make_rows_from_row_metas(&field_metas, row_metas); + grid_blocks.push(GridBlock::new(&grid_block_meta.block_id, rows)); + } + } + } + + Ok(grid_blocks.into()) } 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 36c202f335..dcc077be35 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -4,7 +4,7 @@ use chrono::NaiveDateTime; use flowy_grid::services::cell::*; use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, RowMetaContextBuilder}; use flowy_grid_data_model::entities::{ - CellMetaChangeset, FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMetaChangeset, + CellMetaChangeset, FieldChangeset, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset, }; #[tokio::test] @@ -135,7 +135,7 @@ async fn grid_delete_field() { #[tokio::test] async fn grid_create_block() { - let grid_block = GridBlock::new(); + let grid_block = GridBlockMeta::new(); let scripts = vec![ AssertBlockCount(1), CreateBlock { block: grid_block }, @@ -146,10 +146,10 @@ async fn grid_create_block() { #[tokio::test] async fn grid_update_block() { - let grid_block = GridBlock::new(); + let grid_block = GridBlockMeta::new(); let mut cloned_grid_block = grid_block.clone(); - let changeset = GridBlockChangeset { - block_id: grid_block.id.clone(), + let changeset = GridBlockMetaChangeset { + block_id: grid_block.block_id.clone(), start_row_index: Some(2), row_count: Some(10), }; @@ -377,7 +377,7 @@ async fn grid_cell_update() { assert_eq!(row_metas.len(), 3); assert_eq!(grid_blocks.len(), 1); - let block_id = &grid_blocks.first().unwrap().id; + let block_id = &grid_blocks.first().unwrap().block_id; let mut scripts = vec![]; for (index, row_meta) in row_metas.iter().enumerate() { for field_meta in field_metas { diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 6449d09f6f..20164bca37 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -6,8 +6,8 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::row::RowMetaContext; use flowy_grid_data_model::entities::{ - BuildGridContext, CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlock, GridBlockChangeset, RowMeta, - RowMetaChangeset, + BuildGridContext, CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlockMeta, GridBlockMetaChangeset, + RowMeta, RowMetaChangeset, }; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::helper::ViewTest; @@ -33,10 +33,10 @@ pub enum EditorScript { field_meta: FieldMeta, }, CreateBlock { - block: GridBlock, + block: GridBlockMeta, }, UpdateBlock { - changeset: GridBlockChangeset, + changeset: GridBlockMetaChangeset, }, AssertBlockCount(usize), AssertBlock { @@ -46,7 +46,7 @@ pub enum EditorScript { }, AssertBlockEqual { block_index: usize, - block: GridBlock, + block: GridBlockMeta, }, CreateEmptyRow, CreateRow { @@ -75,7 +75,7 @@ pub struct GridEditorTest { pub grid_id: String, pub editor: Arc, pub field_metas: Vec, - pub grid_blocks: Vec, + pub grid_blocks: Vec, pub row_metas: Vec>, pub field_count: usize, } @@ -90,7 +90,7 @@ impl GridEditorTest { let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); let field_metas = editor.get_field_metas(None).await.unwrap(); let grid_blocks = editor.get_blocks().await.unwrap(); - let row_metas = editor.get_row_metas(None).await.unwrap(); + let row_metas = editor.get_grid_block_meta_snapshots(None).await.unwrap(); let grid_id = test.view.id; Self { @@ -173,18 +173,18 @@ impl GridEditorTest { } EditorScript::CreateEmptyRow => { self.editor.create_row(None).await.unwrap(); - self.row_metas = self.editor.get_row_metas(None).await.unwrap(); + self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); self.grid_blocks = self.editor.get_blocks().await.unwrap(); } EditorScript::CreateRow { context } => { self.editor.insert_rows(vec![context]).await.unwrap(); - self.row_metas = self.editor.get_row_metas(None).await.unwrap(); + self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); self.grid_blocks = self.editor.get_blocks().await.unwrap(); } EditorScript::UpdateRow { changeset: change } => self.editor.update_row(change).await.unwrap(), EditorScript::DeleteRow { row_ids } => { self.editor.delete_rows(row_ids).await.unwrap(); - self.row_metas = self.editor.get_row_metas(None).await.unwrap(); + self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); self.grid_blocks = self.editor.get_blocks().await.unwrap(); } EditorScript::AssertRow { changeset } => { @@ -204,11 +204,11 @@ impl GridEditorTest { assert!(result.is_err()) } else { let _ = result.unwrap(); - self.row_metas = self.editor.get_row_metas(None).await.unwrap(); + self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); } } EditorScript::AssertRowCount(count) => { - assert_eq!(self.editor.get_rows(None).await.unwrap().len(), count); + assert_eq!(self.editor.get_grid_blocks(None).await.unwrap().len(), count); } EditorScript::AssertGridMetaPad => { sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await; diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_data_pad.rs similarity index 85% rename from shared-lib/flowy-collaboration/src/client_grid/block_pad.rs rename to shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_data_pad.rs index c1673259e9..dd62c787d3 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_data_pad.rs @@ -1,7 +1,7 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{GridBlockMeta, RowMeta, RowMetaChangeset}; +use flowy_grid_data_model::entities::{GridBlockMetaData, RowMeta, RowMetaChangeset}; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use serde::{Deserialize, Serialize}; @@ -12,7 +12,7 @@ pub type GridBlockMetaDelta = PlainTextDelta; pub type GridBlockMetaDeltaBuilder = PlainTextDeltaBuilder; #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct GridBlockMetaPad { +pub struct GridBlockMetaDataPad { block_id: String, rows: Vec>, @@ -20,14 +20,18 @@ pub struct GridBlockMetaPad { pub(crate) delta: GridBlockMetaDelta, } -impl GridBlockMetaPad { +impl GridBlockMetaDataPad { pub fn from_delta(delta: GridBlockMetaDelta) -> CollaborateResult { let s = delta.to_str()?; - let block_meta: GridBlockMeta = serde_json::from_str(&s).map_err(|e| { + let block_meta: GridBlockMetaData = serde_json::from_str(&s).map_err(|e| { CollaborateError::internal().context(format!("Deserialize delta to block meta failed: {}", e)) })?; let block_id = block_meta.block_id; - let rows = block_meta.rows.into_iter().map(Arc::new).collect::>>(); + let rows = block_meta + .row_metas + .into_iter() + .map(Arc::new) + .collect::>>(); Ok(Self { block_id, rows, delta }) } @@ -39,10 +43,10 @@ impl GridBlockMetaPad { pub fn add_row( &mut self, row: RowMeta, - upper_row_id: Option, - ) -> CollaborateResult> { + start_row_id: Option, + ) -> CollaborateResult> { self.modify(|rows| { - if let Some(upper_row_id) = upper_row_id { + if let Some(upper_row_id) = start_row_id { if upper_row_id.is_empty() { rows.insert(0, Arc::new(row)); return Ok(Some(())); @@ -59,7 +63,7 @@ impl GridBlockMetaPad { }) } - pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { + pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { self.modify(|rows| { rows.retain(|row| !row_ids.contains(&row.id)); Ok(Some(())) @@ -94,7 +98,7 @@ impl GridBlockMetaPad { self.rows.len() as i32 } - pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { + pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { let row_id = changeset.row_id.clone(); self.modify_row(&row_id, |row| { let mut is_changed = None; @@ -119,7 +123,7 @@ impl GridBlockMetaPad { }) } - pub fn modify(&mut self, f: F) -> CollaborateResult> + pub fn modify(&mut self, f: F) -> CollaborateResult> where F: for<'a> FnOnce(&'a mut Vec>) -> CollaborateResult>, { @@ -133,14 +137,14 @@ impl GridBlockMetaPad { None => Ok(None), Some(delta) => { self.delta = self.delta.compose(&delta)?; - Ok(Some(GridBlockMetaChange { delta, md5: self.md5() })) + Ok(Some(GridBlockMetaDataChange { delta, md5: self.md5() })) } } } } } - fn modify_row(&mut self, row_id: &str, f: F) -> CollaborateResult> + fn modify_row(&mut self, row_id: &str, f: F) -> CollaborateResult> where F: FnOnce(&mut RowMeta) -> CollaborateResult>, { @@ -168,35 +172,35 @@ impl GridBlockMetaPad { } } -pub struct GridBlockMetaChange { +pub struct GridBlockMetaDataChange { pub delta: GridBlockMetaDelta, /// md5: the md5 of the grid after applying the change. pub md5: String, } -pub fn make_block_meta_delta(block_meta: &GridBlockMeta) -> GridBlockMetaDelta { - let json = serde_json::to_string(&block_meta).unwrap(); +pub fn make_block_meta_delta(grid_block_meta_data: &GridBlockMetaData) -> GridBlockMetaDelta { + let json = serde_json::to_string(&grid_block_meta_data).unwrap(); PlainTextDeltaBuilder::new().insert(&json).build() } -pub fn make_block_meta_revisions(user_id: &str, block_meta: &GridBlockMeta) -> RepeatedRevision { - let delta = make_block_meta_delta(block_meta); +pub fn make_block_meta_revisions(user_id: &str, grid_block_meta_data: &GridBlockMetaData) -> RepeatedRevision { + let delta = make_block_meta_delta(grid_block_meta_data); let bytes = delta.to_delta_bytes(); - let revision = Revision::initial_revision(user_id, &block_meta.block_id, bytes); + let revision = Revision::initial_revision(user_id, &grid_block_meta_data.block_id, bytes); revision.into() } -impl std::default::Default for GridBlockMetaPad { +impl std::default::Default for GridBlockMetaDataPad { fn default() -> Self { - let block_meta = GridBlockMeta { + let block_meta_data = GridBlockMetaData { block_id: uuid(), - rows: vec![], + row_metas: vec![], }; - let delta = make_block_meta_delta(&block_meta); - GridBlockMetaPad { - block_id: block_meta.block_id, - rows: block_meta.rows.into_iter().map(Arc::new).collect::>(), + let delta = make_block_meta_delta(&block_meta_data); + GridBlockMetaDataPad { + block_id: block_meta_data.block_id, + rows: block_meta_data.row_metas.into_iter().map(Arc::new).collect::>(), delta, } } @@ -204,7 +208,7 @@ impl std::default::Default for GridBlockMetaPad { #[cfg(test)] mod tests { - use crate::client_grid::{GridBlockMetaDelta, GridBlockMetaPad}; + use crate::client_grid::{GridBlockMetaDataPad, GridBlockMetaDelta}; use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset}; #[test] @@ -255,7 +259,7 @@ mod tests { assert_eq!(*pad.rows[2], row_2); } - fn test_row_meta(id: &str, pad: &GridBlockMetaPad) -> RowMeta { + fn test_row_meta(id: &str, pad: &GridBlockMetaDataPad) -> RowMeta { RowMeta { id: id.to_string(), block_id: pad.block_id.clone(), @@ -351,8 +355,8 @@ mod tests { ); } - fn test_pad() -> GridBlockMetaPad { + fn test_pad() -> GridBlockMetaDataPad { let delta = GridBlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap(); - GridBlockMetaPad::from_delta(delta).unwrap() + GridBlockMetaDataPad::from_delta(delta).unwrap() } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index a6be909ef6..3eb8af06c3 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -13,8 +13,8 @@ impl GridBuilder { } pub fn add_empty_row(mut self) -> Self { - let row = RowMeta::new(&self.build_context.grid_block.id); - self.build_context.grid_block_meta.rows.push(row); + let row = RowMeta::new(&self.build_context.grid_block.block_id); + self.build_context.grid_block_meta_data.row_metas.push(row); self.build_context.grid_block.row_count += 1; self } @@ -41,7 +41,7 @@ fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> { mod tests { use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBuilder}; - use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMeta, GridMeta}; + use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMetaData, GridMeta}; #[test] fn create_default_grid_test() { @@ -63,7 +63,7 @@ mod tests { let grid_meta_delta = make_grid_delta(&grid_meta); let _: GridMeta = serde_json::from_str(&grid_meta_delta.to_str().unwrap()).unwrap(); - let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta); - let _: GridBlockMeta = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap(); + let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta_data); + let _: GridBlockMetaData = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap(); } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs index a403b9c1c9..31c6ed0fbf 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs @@ -3,7 +3,7 @@ use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use bytes::Bytes; use flowy_grid_data_model::entities::{ - FieldChangeset, FieldMeta, FieldOrder, GridBlock, GridBlockChangeset, GridMeta, RepeatedFieldOrder, + FieldChangeset, FieldMeta, FieldOrder, GridBlockMeta, GridBlockMetaChangeset, GridMeta, RepeatedFieldOrder, }; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; @@ -138,9 +138,9 @@ impl GridMetaPad { }) } - pub fn create_block(&mut self, block: GridBlock) -> CollaborateResult> { + pub fn create_block(&mut self, block: GridBlockMeta) -> CollaborateResult> { self.modify_grid(|grid| { - if grid.blocks.iter().any(|b| b.id == block.id) { + if grid.blocks.iter().any(|b| b.block_id == block.block_id) { tracing::warn!("Duplicate grid block"); Ok(None) } else { @@ -161,11 +161,11 @@ impl GridMetaPad { }) } - pub fn get_blocks(&self) -> Vec { + pub fn get_blocks(&self) -> Vec { self.grid_meta.blocks.clone() } - pub fn update_block(&mut self, changeset: GridBlockChangeset) -> CollaborateResult> { + pub fn update_block(&mut self, changeset: GridBlockMetaChangeset) -> CollaborateResult> { let block_id = changeset.block_id.clone(); self.modify_block(&block_id, |block| { let mut is_changed = None; @@ -223,15 +223,17 @@ impl GridMetaPad { pub fn modify_block(&mut self, block_id: &str, f: F) -> CollaborateResult> where - F: FnOnce(&mut GridBlock) -> CollaborateResult>, + F: FnOnce(&mut GridBlockMeta) -> CollaborateResult>, { - self.modify_grid(|grid| match grid.blocks.iter().position(|block| block.id == block_id) { - None => { - tracing::warn!("[GridMetaPad]: Can't find any block with id: {}", block_id); - Ok(None) - } - Some(index) => f(&mut grid.blocks[index]), - }) + self.modify_grid( + |grid| match grid.blocks.iter().position(|block| block.block_id == block_id) { + None => { + tracing::warn!("[GridMetaPad]: Can't find any block with id: {}", block_id); + Ok(None) + } + Some(index) => f(&mut grid.blocks[index]), + }, + ) } pub fn modify_field(&mut self, field_id: &str, f: F) -> CollaborateResult> diff --git a/shared-lib/flowy-collaboration/src/client_grid/mod.rs b/shared-lib/flowy-collaboration/src/client_grid/mod.rs index 9dcb155557..f41d3601b4 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/mod.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/mod.rs @@ -1,7 +1,7 @@ -mod block_pad; +mod grid_block_meta_data_pad; mod grid_builder; mod grid_meta_pad; -pub use block_pad::*; +pub use grid_block_meta_data_pad::*; pub use grid_builder::*; pub use grid_meta_pad::*; 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 36e8e211e3..b3aa069170 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,6 +1,7 @@ -use crate::entities::{FieldMeta, FieldType, RowMeta}; +use crate::entities::{FieldMeta, FieldType, GridBlockMeta, RowMeta}; use flowy_derive::ProtoBuf; use std::collections::HashMap; +use std::hash::Hash; use std::sync::Arc; #[derive(Debug, Clone, Default, ProtoBuf)] @@ -12,7 +13,7 @@ pub struct Grid { pub field_orders: Vec, #[pb(index = 3)] - pub row_orders: Vec, + pub blocks: Vec, } #[derive(Debug, Clone, Default, ProtoBuf)] @@ -150,6 +151,12 @@ impl std::ops::DerefMut for RepeatedRowOrder { } } +impl std::convert::From> for RepeatedRowOrder { + fn from(items: Vec) -> Self { + Self { items } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct Row { #[pb(index = 1)] @@ -163,29 +170,35 @@ pub struct Row { } #[derive(Debug, Default, ProtoBuf)] -pub struct RepeatedRow { +pub struct RepeatedGridBlock { #[pb(index = 1)] - pub items: Vec, + pub items: Vec, } -impl std::ops::Deref for RepeatedRow { - type Target = Vec; - fn deref(&self) -> &Self::Target { - &self.items - } -} - -impl std::ops::DerefMut for RepeatedRow { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.items - } -} - -impl std::convert::From> for RepeatedRow { - fn from(items: Vec) -> Self { +impl std::convert::From> for RepeatedGridBlock { + fn from(items: Vec) -> Self { Self { items } } } + +#[derive(Debug, Default, ProtoBuf)] +pub struct GridBlock { + #[pb(index = 1)] + pub block_id: String, + + #[pb(index = 2)] + pub rows: Vec, +} + +impl GridBlock { + pub fn new(block_id: &str, rows: Vec) -> Self { + Self { + block_id: block_id.to_owned(), + rows, + } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct Cell { #[pb(index = 1)] @@ -247,6 +260,18 @@ impl AsRef for GridId { } } +#[derive(Clone, ProtoBuf, Default, Debug)] +pub struct GridBlockId { + #[pb(index = 1)] + pub value: String, +} + +impl AsRef for GridBlockId { + fn as_ref(&self) -> &str { + &self.value + } +} + #[derive(ProtoBuf, Default)] pub struct CreateRowPayload { #[pb(index = 1)] @@ -266,10 +291,10 @@ pub struct QueryFieldPayload { } #[derive(ProtoBuf, Default)] -pub struct QueryRowPayload { +pub struct QueryGridBlocksPayload { #[pb(index = 1)] pub grid_id: String, #[pb(index = 2)] - pub row_orders: RepeatedRowOrder, + pub blocks: Vec, } diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 34d323c5df..62a545fcb0 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -16,13 +16,13 @@ pub struct GridMeta { pub fields: Vec, #[pb(index = 3)] - pub blocks: Vec, + pub blocks: Vec, } #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] -pub struct GridBlock { +pub struct GridBlockMeta { #[pb(index = 1)] - pub id: String, + pub block_id: String, #[pb(index = 2)] pub start_row_index: i32, @@ -31,7 +31,7 @@ pub struct GridBlock { pub row_count: i32, } -impl GridBlock { +impl GridBlockMeta { pub fn len(&self) -> i32 { self.start_row_index + self.row_count } @@ -41,22 +41,22 @@ impl GridBlock { } } -impl GridBlock { +impl GridBlockMeta { pub fn new() -> Self { - GridBlock { - id: uuid::Uuid::new_v4().to_string(), + GridBlockMeta { + block_id: uuid::Uuid::new_v4().to_string(), ..Default::default() } } } -pub struct GridBlockChangeset { +pub struct GridBlockMetaChangeset { pub block_id: String, pub start_row_index: Option, pub row_count: Option, } -impl GridBlockChangeset { +impl GridBlockMetaChangeset { pub fn from_row_count(block_id: &str, row_count: i32) -> Self { Self { block_id: block_id.to_string(), @@ -67,12 +67,12 @@ impl GridBlockChangeset { } #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] -pub struct GridBlockMeta { +pub struct GridBlockMetaData { #[pb(index = 1)] pub block_id: String, #[pb(index = 2)] - pub rows: Vec, + pub row_metas: Vec, } #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf, PartialEq, Eq)] @@ -329,24 +329,24 @@ pub struct BuildGridContext { pub field_metas: Vec, #[pb(index = 2)] - pub grid_block: GridBlock, + pub grid_block: GridBlockMeta, #[pb(index = 3)] - pub grid_block_meta: GridBlockMeta, + pub grid_block_meta_data: GridBlockMetaData, } impl std::default::Default for BuildGridContext { fn default() -> Self { - let grid_block = GridBlock::new(); - let grid_block_meta = GridBlockMeta { - block_id: grid_block.id.clone(), - rows: vec![], + let grid_block = GridBlockMeta::new(); + let grid_block_meta_data = GridBlockMetaData { + block_id: grid_block.block_id.clone(), + row_metas: vec![], }; Self { field_metas: vec![], grid_block, - grid_block_meta, + grid_block_meta_data, } } } 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 9702766975..6e76d92a7c 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 @@ -28,7 +28,7 @@ pub struct Grid { // message fields pub id: ::std::string::String, pub field_orders: ::protobuf::RepeatedField, - pub row_orders: ::protobuf::RepeatedField, + pub blocks: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -96,29 +96,29 @@ impl Grid { ::std::mem::replace(&mut self.field_orders, ::protobuf::RepeatedField::new()) } - // repeated .RowOrder row_orders = 3; + // repeated .GridBlockMeta blocks = 3; - pub fn get_row_orders(&self) -> &[RowOrder] { - &self.row_orders + pub fn get_blocks(&self) -> &[super::meta::GridBlockMeta] { + &self.blocks } - pub fn clear_row_orders(&mut self) { - self.row_orders.clear(); + pub fn clear_blocks(&mut self) { + self.blocks.clear(); } // Param is passed by value, moved - pub fn set_row_orders(&mut self, v: ::protobuf::RepeatedField) { - self.row_orders = v; + pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { + self.blocks = v; } // Mutable pointer to the field. - pub fn mut_row_orders(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.row_orders + pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.blocks } // Take field - pub fn take_row_orders(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.row_orders, ::protobuf::RepeatedField::new()) + pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) } } @@ -129,7 +129,7 @@ impl ::protobuf::Message for Grid { return false; } }; - for v in &self.row_orders { + for v in &self.blocks { if !v.is_initialized() { return false; } @@ -148,7 +148,7 @@ impl ::protobuf::Message for Grid { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.field_orders)?; }, 3 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.row_orders)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -169,7 +169,7 @@ impl ::protobuf::Message for Grid { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; - for value in &self.row_orders { + for value in &self.blocks { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; @@ -187,7 +187,7 @@ impl ::protobuf::Message for Grid { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; }; - for v in &self.row_orders { + for v in &self.blocks { os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -240,10 +240,10 @@ impl ::protobuf::Message for Grid { |m: &Grid| { &m.field_orders }, |m: &mut Grid| { &mut m.field_orders }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "row_orders", - |m: &Grid| { &m.row_orders }, - |m: &mut Grid| { &mut m.row_orders }, + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "blocks", + |m: &Grid| { &m.blocks }, + |m: &mut Grid| { &mut m.blocks }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "Grid", @@ -263,7 +263,7 @@ impl ::protobuf::Clear for Grid { fn clear(&mut self) { self.id.clear(); self.field_orders.clear(); - self.row_orders.clear(); + self.blocks.clear(); self.unknown_fields.clear(); } } @@ -1749,29 +1749,29 @@ impl ::protobuf::reflect::ProtobufValue for Row { } #[derive(PartialEq,Clone,Default)] -pub struct RepeatedRow { +pub struct RepeatedGridBlock { // message fields - pub items: ::protobuf::RepeatedField, + pub items: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a RepeatedRow { - fn default() -> &'a RepeatedRow { - ::default_instance() +impl<'a> ::std::default::Default for &'a RepeatedGridBlock { + fn default() -> &'a RepeatedGridBlock { + ::default_instance() } } -impl RepeatedRow { - pub fn new() -> RepeatedRow { +impl RepeatedGridBlock { + pub fn new() -> RepeatedGridBlock { ::std::default::Default::default() } - // repeated .Row items = 1; + // repeated .GridBlock items = 1; - pub fn get_items(&self) -> &[Row] { + pub fn get_items(&self) -> &[GridBlock] { &self.items } pub fn clear_items(&mut self) { @@ -1779,22 +1779,22 @@ impl RepeatedRow { } // Param is passed by value, moved - pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { + pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { self.items = v; } // Mutable pointer to the field. - pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { + pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { &mut self.items } // Take field - pub fn take_items(&mut self) -> ::protobuf::RepeatedField { + pub fn take_items(&mut self) -> ::protobuf::RepeatedField { ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) } } -impl ::protobuf::Message for RepeatedRow { +impl ::protobuf::Message for RepeatedGridBlock { fn is_initialized(&self) -> bool { for v in &self.items { if !v.is_initialized() { @@ -1868,47 +1868,255 @@ impl ::protobuf::Message for RepeatedRow { Self::descriptor_static() } - fn new() -> RepeatedRow { - RepeatedRow::new() + fn new() -> RepeatedGridBlock { + RepeatedGridBlock::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "items", - |m: &RepeatedRow| { &m.items }, - |m: &mut RepeatedRow| { &mut m.items }, + |m: &RepeatedGridBlock| { &m.items }, + |m: &mut RepeatedGridBlock| { &mut m.items }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RepeatedRow", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedGridBlock", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static RepeatedRow { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RepeatedRow::new) + fn default_instance() -> &'static RepeatedGridBlock { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedGridBlock::new) } } -impl ::protobuf::Clear for RepeatedRow { +impl ::protobuf::Clear for RepeatedGridBlock { fn clear(&mut self) { self.items.clear(); self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for RepeatedRow { +impl ::std::fmt::Debug for RepeatedGridBlock { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for RepeatedRow { +impl ::protobuf::reflect::ProtobufValue for RepeatedGridBlock { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct GridBlock { + // message fields + pub block_id: ::std::string::String, + pub rows: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridBlock { + fn default() -> &'a GridBlock { + ::default_instance() + } +} + +impl GridBlock { + pub fn new() -> GridBlock { + ::std::default::Default::default() + } + + // string block_id = 1; + + + pub fn get_block_id(&self) -> &str { + &self.block_id + } + pub fn clear_block_id(&mut self) { + self.block_id.clear(); + } + + // Param is passed by value, moved + pub fn set_block_id(&mut self, v: ::std::string::String) { + self.block_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id + } + + // Take field + pub fn take_block_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) + } + + // repeated .Row rows = 2; + + + pub fn get_rows(&self) -> &[Row] { + &self.rows + } + pub fn clear_rows(&mut self) { + self.rows.clear(); + } + + // Param is passed by value, moved + pub fn set_rows(&mut self, v: ::protobuf::RepeatedField) { + self.rows = v; + } + + // Mutable pointer to the field. + pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.rows + } + + // Take field + pub fn take_rows(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for GridBlock { + fn is_initialized(&self) -> bool { + for v in &self.rows { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; + }, + 2 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.block_id); + } + for value in &self.rows { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.block_id.is_empty() { + os.write_string(1, &self.block_id)?; + } + for v in &self.rows { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> GridBlock { + GridBlock::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "block_id", + |m: &GridBlock| { &m.block_id }, + |m: &mut GridBlock| { &mut m.block_id }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "rows", + |m: &GridBlock| { &m.rows }, + |m: &mut GridBlock| { &mut m.rows }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlock", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridBlock { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlock::new) + } +} + +impl ::protobuf::Clear for GridBlock { + fn clear(&mut self) { + self.block_id.clear(); + self.rows.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridBlock { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridBlock { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -2599,6 +2807,165 @@ impl ::protobuf::reflect::ProtobufValue for GridId { } } +#[derive(PartialEq,Clone,Default)] +pub struct GridBlockId { + // message fields + pub value: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridBlockId { + fn default() -> &'a GridBlockId { + ::default_instance() + } +} + +impl GridBlockId { + pub fn new() -> GridBlockId { + ::std::default::Default::default() + } + + // string value = 1; + + + pub fn get_value(&self) -> &str { + &self.value + } + pub fn clear_value(&mut self) { + self.value.clear(); + } + + // Param is passed by value, moved + pub fn set_value(&mut self, v: ::std::string::String) { + self.value = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_value(&mut self) -> &mut ::std::string::String { + &mut self.value + } + + // Take field + pub fn take_value(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.value, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for GridBlockId { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.value)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.value.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.value); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.value.is_empty() { + os.write_string(1, &self.value)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> GridBlockId { + GridBlockId::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "value", + |m: &GridBlockId| { &m.value }, + |m: &mut GridBlockId| { &mut m.value }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlockId", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridBlockId { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlockId::new) + } +} + +impl ::protobuf::Clear for GridBlockId { + fn clear(&mut self) { + self.value.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridBlockId { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridBlockId { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct CreateRowPayload { // message fields @@ -3057,23 +3424,23 @@ impl ::protobuf::reflect::ProtobufValue for QueryFieldPayload { } #[derive(PartialEq,Clone,Default)] -pub struct QueryRowPayload { +pub struct QueryGridBlocksPayload { // message fields pub grid_id: ::std::string::String, - pub row_orders: ::protobuf::SingularPtrField, + pub blocks: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a QueryRowPayload { - fn default() -> &'a QueryRowPayload { - ::default_instance() +impl<'a> ::std::default::Default for &'a QueryGridBlocksPayload { + fn default() -> &'a QueryGridBlocksPayload { + ::default_instance() } } -impl QueryRowPayload { - pub fn new() -> QueryRowPayload { +impl QueryGridBlocksPayload { + pub fn new() -> QueryGridBlocksPayload { ::std::default::Default::default() } @@ -3103,43 +3470,35 @@ impl QueryRowPayload { ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) } - // .RepeatedRowOrder row_orders = 2; + // repeated .GridBlockMeta blocks = 2; - pub fn get_row_orders(&self) -> &RepeatedRowOrder { - self.row_orders.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_blocks(&self) -> &[super::meta::GridBlockMeta] { + &self.blocks } - pub fn clear_row_orders(&mut self) { - self.row_orders.clear(); - } - - pub fn has_row_orders(&self) -> bool { - self.row_orders.is_some() + pub fn clear_blocks(&mut self) { + self.blocks.clear(); } // Param is passed by value, moved - pub fn set_row_orders(&mut self, v: RepeatedRowOrder) { - self.row_orders = ::protobuf::SingularPtrField::some(v); + pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { + self.blocks = v; } // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_row_orders(&mut self) -> &mut RepeatedRowOrder { - if self.row_orders.is_none() { - self.row_orders.set_default(); - } - self.row_orders.as_mut().unwrap() + pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.blocks } // Take field - pub fn take_row_orders(&mut self) -> RepeatedRowOrder { - self.row_orders.take().unwrap_or_else(|| RepeatedRowOrder::new()) + pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) } } -impl ::protobuf::Message for QueryRowPayload { +impl ::protobuf::Message for QueryGridBlocksPayload { fn is_initialized(&self) -> bool { - for v in &self.row_orders { + for v in &self.blocks { if !v.is_initialized() { return false; } @@ -3155,7 +3514,7 @@ impl ::protobuf::Message for QueryRowPayload { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; }, 2 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.row_orders)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -3172,10 +3531,10 @@ impl ::protobuf::Message for QueryRowPayload { if !self.grid_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.grid_id); } - if let Some(ref v) = self.row_orders.as_ref() { - let len = v.compute_size(); + for value in &self.blocks { + let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } + }; my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -3185,11 +3544,11 @@ impl ::protobuf::Message for QueryRowPayload { if !self.grid_id.is_empty() { os.write_string(1, &self.grid_id)?; } - if let Some(ref v) = self.row_orders.as_ref() { + for v in &self.blocks { os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; - } + }; os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -3220,8 +3579,8 @@ impl ::protobuf::Message for QueryRowPayload { Self::descriptor_static() } - fn new() -> QueryRowPayload { - QueryRowPayload::new() + fn new() -> QueryGridBlocksPayload { + QueryGridBlocksPayload::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -3230,59 +3589,59 @@ impl ::protobuf::Message for QueryRowPayload { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "grid_id", - |m: &QueryRowPayload| { &m.grid_id }, - |m: &mut QueryRowPayload| { &mut m.grid_id }, + |m: &QueryGridBlocksPayload| { &m.grid_id }, + |m: &mut QueryGridBlocksPayload| { &mut m.grid_id }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "row_orders", - |m: &QueryRowPayload| { &m.row_orders }, - |m: &mut QueryRowPayload| { &mut m.row_orders }, + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "blocks", + |m: &QueryGridBlocksPayload| { &m.blocks }, + |m: &mut QueryGridBlocksPayload| { &mut m.blocks }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "QueryRowPayload", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "QueryGridBlocksPayload", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static QueryRowPayload { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(QueryRowPayload::new) + fn default_instance() -> &'static QueryGridBlocksPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(QueryGridBlocksPayload::new) } } -impl ::protobuf::Clear for QueryRowPayload { +impl ::protobuf::Clear for QueryGridBlocksPayload { fn clear(&mut self) { self.grid_id.clear(); - self.row_orders.clear(); + self.blocks.clear(); self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for QueryRowPayload { +impl ::std::fmt::Debug for QueryGridBlocksPayload { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for QueryRowPayload { +impl ::protobuf::reflect::ProtobufValue for QueryGridBlocksPayload { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ngrid.proto\x1a\nmeta.proto\"p\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\ + \n\ngrid.proto\x1a\nmeta.proto\"n\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\ \x01(\tR\x02id\x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrd\ - erR\x0bfieldOrders\x12(\n\nrow_orders\x18\x03\x20\x03(\x0b2\t.RowOrderR\ - \trowOrders\"\xb8\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02\ - id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\ - \x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.Fiel\ - dTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06frozen\ - \x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05wi\ - dth\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\x19\n\x08field_i\ - d\x18\x01\x20\x01(\tR\x07fieldId\"-\n\rRepeatedField\x12\x1c\n\x05items\ + erR\x0bfieldOrders\x12&\n\x06blocks\x18\x03\x20\x03(\x0b2\x0e.GridBlockM\ + etaR\x06blocks\"\xb8\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ + \x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ + \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\ + FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ + n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ + idth\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\x19\n\x08field_\ + id\x18\x01\x20\x01(\tR\x07fieldId\"-\n\rRepeatedField\x12\x1c\n\x05items\ \x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFieldOrder\ \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"<\n\x08\ RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08b\ @@ -3292,20 +3651,23 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\ \x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldId\ Entry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\ - \x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\ - \x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05items\";\n\x04Cell\x12\ - \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\ - \x18\x02\x20\x01(\tR\x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\ - \x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\ - \x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\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\x0cupper_row_id\x18\ - \x02\x20\x01(\tH\0R\nupperRowIdB\x15\n\x13one_of_upper_row_id\"d\n\x11Qu\ - eryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\ - \n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfiel\ - dOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\t\ - R\x06gridId\x120\n\nrow_orders\x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrde\ - rR\trowOrdersb\x06proto3\ + \x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\"5\n\x11RepeatedGridBloc\ + k\x12\x20\n\x05items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"@\n\tG\ + ridBlock\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x18\n\ + \x04rows\x18\x02\x20\x03(\x0b2\x04.RowR\x04rows\";\n\x04Cell\x12\x19\n\ + \x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\ + \x20\x01(\tR\x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\ + \x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\ + \x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05valu\ + e\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\x0cupper_row_id\x18\x02\x20\ + \x01(\tH\0R\nupperRowIdB\x15\n\x13one_of_upper_row_id\"d\n\x11QueryField\ + Payload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfie\ + ld_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\ + Y\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \x06gridId\x12&\n\x06blocks\x18\x02\x20\x03(\x0b2\x0e.GridBlockMetaR\x06\ + blocksb\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/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index d56f2ee5a3..0dcde28a6b 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -28,7 +28,7 @@ pub struct GridMeta { // message fields pub grid_id: ::std::string::String, pub fields: ::protobuf::RepeatedField, - pub blocks: ::protobuf::RepeatedField, + pub blocks: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -96,10 +96,10 @@ impl GridMeta { ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new()) } - // repeated .GridBlock blocks = 3; + // repeated .GridBlockMeta blocks = 3; - pub fn get_blocks(&self) -> &[GridBlock] { + pub fn get_blocks(&self) -> &[GridBlockMeta] { &self.blocks } pub fn clear_blocks(&mut self) { @@ -107,17 +107,17 @@ impl GridMeta { } // Param is passed by value, moved - pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { + pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { self.blocks = v; } // Mutable pointer to the field. - pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { + pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { &mut self.blocks } // Take field - pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { + pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) } } @@ -240,7 +240,7 @@ impl ::protobuf::Message for GridMeta { |m: &GridMeta| { &m.fields }, |m: &mut GridMeta| { &mut m.fields }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "blocks", |m: &GridMeta| { &m.blocks }, |m: &mut GridMeta| { &mut m.blocks }, @@ -280,240 +280,12 @@ impl ::protobuf::reflect::ProtobufValue for GridMeta { } } -#[derive(PartialEq,Clone,Default)] -pub struct GridBlock { - // message fields - pub id: ::std::string::String, - pub start_row_index: i32, - pub row_count: i32, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a GridBlock { - fn default() -> &'a GridBlock { - ::default_instance() - } -} - -impl GridBlock { - pub fn new() -> GridBlock { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // int32 start_row_index = 2; - - - pub fn get_start_row_index(&self) -> i32 { - self.start_row_index - } - pub fn clear_start_row_index(&mut self) { - self.start_row_index = 0; - } - - // Param is passed by value, moved - pub fn set_start_row_index(&mut self, v: i32) { - self.start_row_index = v; - } - - // int32 row_count = 3; - - - pub fn get_row_count(&self) -> i32 { - self.row_count - } - pub fn clear_row_count(&mut self) { - self.row_count = 0; - } - - // Param is passed by value, moved - pub fn set_row_count(&mut self, v: i32) { - self.row_count = v; - } -} - -impl ::protobuf::Message for GridBlock { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.start_row_index = tmp; - }, - 3 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_int32()?; - self.row_count = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if self.start_row_index != 0 { - my_size += ::protobuf::rt::value_size(2, self.start_row_index, ::protobuf::wire_format::WireTypeVarint); - } - if self.row_count != 0 { - my_size += ::protobuf::rt::value_size(3, self.row_count, ::protobuf::wire_format::WireTypeVarint); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if self.start_row_index != 0 { - os.write_int32(2, self.start_row_index)?; - } - if self.row_count != 0 { - os.write_int32(3, self.row_count)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> GridBlock { - GridBlock::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &GridBlock| { &m.id }, - |m: &mut GridBlock| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "start_row_index", - |m: &GridBlock| { &m.start_row_index }, - |m: &mut GridBlock| { &mut m.start_row_index }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "row_count", - |m: &GridBlock| { &m.row_count }, - |m: &mut GridBlock| { &mut m.row_count }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GridBlock", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static GridBlock { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GridBlock::new) - } -} - -impl ::protobuf::Clear for GridBlock { - fn clear(&mut self) { - self.id.clear(); - self.start_row_index = 0; - self.row_count = 0; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for GridBlock { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for GridBlock { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct GridBlockMeta { // message fields pub block_id: ::std::string::String, - pub rows: ::protobuf::RepeatedField, + pub start_row_index: i32, + pub row_count: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -556,39 +328,39 @@ impl GridBlockMeta { ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) } - // repeated .RowMeta rows = 2; + // int32 start_row_index = 2; - pub fn get_rows(&self) -> &[RowMeta] { - &self.rows + pub fn get_start_row_index(&self) -> i32 { + self.start_row_index } - pub fn clear_rows(&mut self) { - self.rows.clear(); + pub fn clear_start_row_index(&mut self) { + self.start_row_index = 0; } // Param is passed by value, moved - pub fn set_rows(&mut self, v: ::protobuf::RepeatedField) { - self.rows = v; + pub fn set_start_row_index(&mut self, v: i32) { + self.start_row_index = v; } - // Mutable pointer to the field. - pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.rows + // int32 row_count = 3; + + + pub fn get_row_count(&self) -> i32 { + self.row_count + } + pub fn clear_row_count(&mut self) { + self.row_count = 0; } - // Take field - pub fn take_rows(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new()) + // Param is passed by value, moved + pub fn set_row_count(&mut self, v: i32) { + self.row_count = v; } } impl ::protobuf::Message for GridBlockMeta { fn is_initialized(&self) -> bool { - for v in &self.rows { - if !v.is_initialized() { - return false; - } - }; true } @@ -600,7 +372,18 @@ impl ::protobuf::Message for GridBlockMeta { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, 2 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.start_row_index = tmp; + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.row_count = tmp; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -617,10 +400,12 @@ impl ::protobuf::Message for GridBlockMeta { if !self.block_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.block_id); } - for value in &self.rows { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; + if self.start_row_index != 0 { + my_size += ::protobuf::rt::value_size(2, self.start_row_index, ::protobuf::wire_format::WireTypeVarint); + } + if self.row_count != 0 { + my_size += ::protobuf::rt::value_size(3, self.row_count, ::protobuf::wire_format::WireTypeVarint); + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -630,11 +415,12 @@ impl ::protobuf::Message for GridBlockMeta { if !self.block_id.is_empty() { os.write_string(1, &self.block_id)?; } - for v in &self.rows { - os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; + if self.start_row_index != 0 { + os.write_int32(2, self.start_row_index)?; + } + if self.row_count != 0 { + os.write_int32(3, self.row_count)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -678,10 +464,15 @@ impl ::protobuf::Message for GridBlockMeta { |m: &GridBlockMeta| { &m.block_id }, |m: &mut GridBlockMeta| { &mut m.block_id }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "rows", - |m: &GridBlockMeta| { &m.rows }, - |m: &mut GridBlockMeta| { &mut m.rows }, + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "start_row_index", + |m: &GridBlockMeta| { &m.start_row_index }, + |m: &mut GridBlockMeta| { &mut m.start_row_index }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "row_count", + |m: &GridBlockMeta| { &m.row_count }, + |m: &mut GridBlockMeta| { &mut m.row_count }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "GridBlockMeta", @@ -700,7 +491,8 @@ impl ::protobuf::Message for GridBlockMeta { impl ::protobuf::Clear for GridBlockMeta { fn clear(&mut self) { self.block_id.clear(); - self.rows.clear(); + self.start_row_index = 0; + self.row_count = 0; self.unknown_fields.clear(); } } @@ -717,6 +509,214 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockMeta { } } +#[derive(PartialEq,Clone,Default)] +pub struct GridBlockMetaData { + // message fields + pub block_id: ::std::string::String, + pub row_metas: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridBlockMetaData { + fn default() -> &'a GridBlockMetaData { + ::default_instance() + } +} + +impl GridBlockMetaData { + pub fn new() -> GridBlockMetaData { + ::std::default::Default::default() + } + + // string block_id = 1; + + + pub fn get_block_id(&self) -> &str { + &self.block_id + } + pub fn clear_block_id(&mut self) { + self.block_id.clear(); + } + + // Param is passed by value, moved + pub fn set_block_id(&mut self, v: ::std::string::String) { + self.block_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id + } + + // Take field + pub fn take_block_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) + } + + // repeated .RowMeta row_metas = 2; + + + pub fn get_row_metas(&self) -> &[RowMeta] { + &self.row_metas + } + pub fn clear_row_metas(&mut self) { + self.row_metas.clear(); + } + + // Param is passed by value, moved + pub fn set_row_metas(&mut self, v: ::protobuf::RepeatedField) { + self.row_metas = v; + } + + // Mutable pointer to the field. + pub fn mut_row_metas(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.row_metas + } + + // Take field + pub fn take_row_metas(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.row_metas, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for GridBlockMetaData { + fn is_initialized(&self) -> bool { + for v in &self.row_metas { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; + }, + 2 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.row_metas)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.block_id); + } + for value in &self.row_metas { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.block_id.is_empty() { + os.write_string(1, &self.block_id)?; + } + for v in &self.row_metas { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> GridBlockMetaData { + GridBlockMetaData::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "block_id", + |m: &GridBlockMetaData| { &m.block_id }, + |m: &mut GridBlockMetaData| { &mut m.block_id }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "row_metas", + |m: &GridBlockMetaData| { &m.row_metas }, + |m: &mut GridBlockMetaData| { &mut m.row_metas }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlockMetaData", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridBlockMetaData { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlockMetaData::new) + } +} + +impl ::protobuf::Clear for GridBlockMetaData { + fn clear(&mut self) { + self.block_id.clear(); + self.row_metas.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridBlockMetaData { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridBlockMetaData { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct FieldMeta { // message fields @@ -3119,8 +3119,8 @@ impl ::protobuf::reflect::ProtobufValue for CellMetaChangeset { pub struct BuildGridContext { // message fields pub field_metas: ::protobuf::RepeatedField, - pub grid_block: ::protobuf::SingularPtrField, - pub grid_block_meta: ::protobuf::SingularPtrField, + pub grid_block: ::protobuf::SingularPtrField, + pub grid_block_meta_data: ::protobuf::SingularPtrField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -3162,11 +3162,11 @@ impl BuildGridContext { ::std::mem::replace(&mut self.field_metas, ::protobuf::RepeatedField::new()) } - // .GridBlock grid_block = 2; + // .GridBlockMeta grid_block = 2; - pub fn get_grid_block(&self) -> &GridBlock { - self.grid_block.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_grid_block(&self) -> &GridBlockMeta { + self.grid_block.as_ref().unwrap_or_else(|| ::default_instance()) } pub fn clear_grid_block(&mut self) { self.grid_block.clear(); @@ -3177,13 +3177,13 @@ impl BuildGridContext { } // Param is passed by value, moved - pub fn set_grid_block(&mut self, v: GridBlock) { + pub fn set_grid_block(&mut self, v: GridBlockMeta) { self.grid_block = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_block(&mut self) -> &mut GridBlock { + pub fn mut_grid_block(&mut self) -> &mut GridBlockMeta { if self.grid_block.is_none() { self.grid_block.set_default(); } @@ -3191,41 +3191,41 @@ impl BuildGridContext { } // Take field - pub fn take_grid_block(&mut self) -> GridBlock { - self.grid_block.take().unwrap_or_else(|| GridBlock::new()) + pub fn take_grid_block(&mut self) -> GridBlockMeta { + self.grid_block.take().unwrap_or_else(|| GridBlockMeta::new()) } - // .GridBlockMeta grid_block_meta = 3; + // .GridBlockMetaData grid_block_meta_data = 3; - pub fn get_grid_block_meta(&self) -> &GridBlockMeta { - self.grid_block_meta.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_grid_block_meta_data(&self) -> &GridBlockMetaData { + self.grid_block_meta_data.as_ref().unwrap_or_else(|| ::default_instance()) } - pub fn clear_grid_block_meta(&mut self) { - self.grid_block_meta.clear(); + pub fn clear_grid_block_meta_data(&mut self) { + self.grid_block_meta_data.clear(); } - pub fn has_grid_block_meta(&self) -> bool { - self.grid_block_meta.is_some() + pub fn has_grid_block_meta_data(&self) -> bool { + self.grid_block_meta_data.is_some() } // Param is passed by value, moved - pub fn set_grid_block_meta(&mut self, v: GridBlockMeta) { - self.grid_block_meta = ::protobuf::SingularPtrField::some(v); + pub fn set_grid_block_meta_data(&mut self, v: GridBlockMetaData) { + self.grid_block_meta_data = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_block_meta(&mut self) -> &mut GridBlockMeta { - if self.grid_block_meta.is_none() { - self.grid_block_meta.set_default(); + pub fn mut_grid_block_meta_data(&mut self) -> &mut GridBlockMetaData { + if self.grid_block_meta_data.is_none() { + self.grid_block_meta_data.set_default(); } - self.grid_block_meta.as_mut().unwrap() + self.grid_block_meta_data.as_mut().unwrap() } // Take field - pub fn take_grid_block_meta(&mut self) -> GridBlockMeta { - self.grid_block_meta.take().unwrap_or_else(|| GridBlockMeta::new()) + pub fn take_grid_block_meta_data(&mut self) -> GridBlockMetaData { + self.grid_block_meta_data.take().unwrap_or_else(|| GridBlockMetaData::new()) } } @@ -3241,7 +3241,7 @@ impl ::protobuf::Message for BuildGridContext { return false; } }; - for v in &self.grid_block_meta { + for v in &self.grid_block_meta_data { if !v.is_initialized() { return false; } @@ -3260,7 +3260,7 @@ impl ::protobuf::Message for BuildGridContext { ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block)?; }, 3 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block_meta)?; + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block_meta_data)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -3282,7 +3282,7 @@ impl ::protobuf::Message for BuildGridContext { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } - if let Some(ref v) = self.grid_block_meta.as_ref() { + if let Some(ref v) = self.grid_block_meta_data.as_ref() { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } @@ -3302,7 +3302,7 @@ impl ::protobuf::Message for BuildGridContext { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; } - if let Some(ref v) = self.grid_block_meta.as_ref() { + if let Some(ref v) = self.grid_block_meta_data.as_ref() { os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -3350,15 +3350,15 @@ impl ::protobuf::Message for BuildGridContext { |m: &BuildGridContext| { &m.field_metas }, |m: &mut BuildGridContext| { &mut m.field_metas }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "grid_block", |m: &BuildGridContext| { &m.grid_block }, |m: &mut BuildGridContext| { &mut m.grid_block }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "grid_block_meta", - |m: &BuildGridContext| { &m.grid_block_meta }, - |m: &mut BuildGridContext| { &mut m.grid_block_meta }, + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "grid_block_meta_data", + |m: &BuildGridContext| { &m.grid_block_meta_data }, + |m: &mut BuildGridContext| { &mut m.grid_block_meta_data }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "BuildGridContext", @@ -3378,7 +3378,7 @@ impl ::protobuf::Clear for BuildGridContext { fn clear(&mut self) { self.field_metas.clear(); self.grid_block.clear(); - self.grid_block_meta.clear(); + self.grid_block_meta_data.clear(); self.unknown_fields.clear(); } } @@ -3458,56 +3458,57 @@ impl ::protobuf::reflect::ProtobufValue for FieldType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\nmeta.proto\"k\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \n\nmeta.proto\"o\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ \x06gridId\x12\"\n\x06fields\x18\x02\x20\x03(\x0b2\n.FieldMetaR\x06field\ - s\x12\"\n\x06blocks\x18\x03\x20\x03(\x0b2\n.GridBlockR\x06blocks\"`\n\tG\ - ridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12&\n\x0fstart_row_i\ - ndex\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\ - \x20\x01(\x05R\x08rowCount\"H\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\ - \x01\x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.\ - RowMetaR\x04rows\"\xdf\x01\n\tFieldMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ - \tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04des\ - c\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n\ - .FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froz\ - en\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05\ - width\x18\x07\x20\x01(\x05R\x05width\x12!\n\x0ctype_options\x18\x08\x20\ - \x01(\tR\x0btypeOptions\"\xfd\x02\n\x0eFieldChangeset\x12\x19\n\x08field\ - _id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04name\x18\x02\x20\x01(\tH\ - \0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12+\n\nf\ - ield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\ - \x06frozen\x18\x05\x20\x01(\x08H\x03R\x06frozen\x12\x20\n\nvisibility\ - \x18\x06\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\x18\x07\x20\ - \x01(\x05H\x05R\x05width\x12#\n\x0ctype_options\x18\x08\x20\x01(\tH\x06R\ - \x0btypeOptionsB\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\x0c\ - one_of_widthB\x15\n\x13one_of_type_options\"8\n\x07AnyData\x12\x17\n\x07\ - type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\x02\x20\x01\ - (\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\ - \tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12D\n\ - \x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByFieldIdEntr\ - yR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\x06height\ - \x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\n\x12CellB\ - yFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05v\ - alue\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\xa7\x02\n\ - \x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\ - \x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\n\nvisib\ - ility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_field_id\ - \x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rcellByFiel\ - dId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\ - \x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\ - \x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"9\n\x08Cell\ - Meta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x12\n\x04d\ - ata\x18\x02\x20\x01(\tR\x04data\"\x83\x01\n\x11CellMetaChangeset\x12\x17\ - \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\x18\x02\ - \x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07field\ - Id\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data\ - \"\xa2\x01\n\x10BuildGridContext\x12+\n\x0bfield_metas\x18\x01\x20\x03(\ - \x0b2\n.FieldMetaR\nfieldMetas\x12)\n\ngrid_block\x18\x02\x20\x01(\x0b2\ - \n.GridBlockR\tgridBlock\x126\n\x0fgrid_block_meta\x18\x03\x20\x01(\x0b2\ - \x0e.GridBlockMetaR\rgridBlockMeta*d\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\x05b\x06proto3\ + s\x12&\n\x06blocks\x18\x03\x20\x03(\x0b2\x0e.GridBlockMetaR\x06blocks\"o\ + \n\rGridBlockMeta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\ + \x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\ + \n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"U\n\x11GridBlockMetaDat\ + a\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_metas\ + \x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xdf\x01\n\tFieldMeta\ + \x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\ + \x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nf\ + ield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06fro\ + zen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\ + \x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\ + \x12!\n\x0ctype_options\x18\x08\x20\x01(\tR\x0btypeOptions\"\xfd\x02\n\ + \x0eFieldChangeset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\ + \x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\ + \x03\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x04\x20\x01(\x0e2\n\ + .FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x05\x20\x01(\x08H\ + \x03R\x06frozen\x12\x20\n\nvisibility\x18\x06\x20\x01(\x08H\x04R\nvisibi\ + lity\x12\x16\n\x05width\x18\x07\x20\x01(\x05H\x05R\x05width\x12#\n\x0cty\ + pe_options\x18\x08\x20\x01(\tH\x06R\x0btypeOptionsB\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\x15\n\x13one_of_type\ + _options\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typ\ + eId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07Row\ + Meta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\ + \x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\ + \x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\ + \x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\ + \x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\ + \x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\ + \x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\ + \x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\ + \0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibili\ + ty\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.Ce\ + llByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\ + \x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\ + \x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one\ + _of_visibility\"9\n\x08CellMeta\x12\x19\n\x08field_id\x18\x01\x20\x01(\t\ + R\x07fieldId\x12\x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"\x83\x01\n\ + \x11CellMetaChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ + \x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\ + \x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\ + \x04dataB\r\n\x0bone_of_data\"\xb3\x01\n\x10BuildGridContext\x12+\n\x0bf\ + ield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12-\n\ngrid_b\ + lock\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\tgridBlock\x12C\n\x14grid_\ + block_meta_data\x18\x03\x20\x01(\x0b2\x12.GridBlockMetaDataR\x11gridBloc\ + kMetaData*d\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\x08Checkbox\x10\x05b\x06prot\ + o3\ "; 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 ed6fc83b65..31119b015d 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 @@ -4,7 +4,7 @@ import "meta.proto"; message Grid { string id = 1; repeated FieldOrder field_orders = 2; - repeated RowOrder row_orders = 3; + repeated GridBlockMeta blocks = 3; } message Field { string id = 1; @@ -36,8 +36,12 @@ message Row { map cell_by_field_id = 2; int32 height = 3; } -message RepeatedRow { - repeated Row items = 1; +message RepeatedGridBlock { + repeated GridBlock items = 1; +} +message GridBlock { + string block_id = 1; + repeated Row rows = 2; } message Cell { string field_id = 1; @@ -52,6 +56,9 @@ message CreateGridPayload { message GridId { string value = 1; } +message GridBlockId { + string value = 1; +} message CreateRowPayload { string grid_id = 1; oneof one_of_upper_row_id { string upper_row_id = 2; }; @@ -60,7 +67,7 @@ message QueryFieldPayload { string grid_id = 1; RepeatedFieldOrder field_orders = 2; } -message QueryRowPayload { +message QueryGridBlocksPayload { string grid_id = 1; - RepeatedRowOrder row_orders = 2; + repeated GridBlockMeta blocks = 2; } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index b1c8b77c40..aa23f08a02 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -3,16 +3,16 @@ syntax = "proto3"; message GridMeta { string grid_id = 1; repeated FieldMeta fields = 2; - repeated GridBlock blocks = 3; -} -message GridBlock { - string id = 1; - int32 start_row_index = 2; - int32 row_count = 3; + repeated GridBlockMeta blocks = 3; } message GridBlockMeta { string block_id = 1; - repeated RowMeta rows = 2; + int32 start_row_index = 2; + int32 row_count = 3; +} +message GridBlockMetaData { + string block_id = 1; + repeated RowMeta row_metas = 2; } message FieldMeta { string id = 1; @@ -63,8 +63,8 @@ message CellMetaChangeset { } message BuildGridContext { repeated FieldMeta field_metas = 1; - GridBlock grid_block = 2; - GridBlockMeta grid_block_meta = 3; + GridBlockMeta grid_block = 2; + GridBlockMetaData grid_block_meta_data = 3; } enum FieldType { RichText = 0; From 9a40fc997450414cc1481b4ede0ee2859347345f Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 17 Mar 2022 20:59:21 +0800 Subject: [PATCH 26/28] chore: lazy load row data --- .../workspace/application/grid/grid_bloc.dart | 90 ++++++++----------- .../flowy-grid/src/dart_notification.rs | 1 + .../src/entities/grid.rs | 2 +- 3 files changed, 40 insertions(+), 53 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart index 8fea0b04df..b5e6cc67d5 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -17,8 +17,6 @@ class GridBloc extends Bloc { final View view; final GridService service; final GridListener listener; - Grid? _grid; - List? _fields; GridBloc({required this.view, required this.service, required this.listener}) : super(GridState.initial()) { on( @@ -27,8 +25,6 @@ class GridBloc extends Bloc { initial: (InitialGrid value) async { await _startGridListening(); await _loadGrid(emit); - await _loadFields(emit); - await _loadGridInfo(emit); }, createRow: (_CreateRow value) { service.createRow(gridId: view.id); @@ -48,17 +44,13 @@ class GridBloc extends Bloc { } Future _startGridListening() async { - listener.createRowNotifier.addPublishListener((result) { - result.fold((repeatedRow) { + listener.blockUpdateNotifier.addPublishListener((result) { + result.fold((blockId) { // - Log.info("$repeatedRow"); + Log.info("$blockId"); }, (err) => null); }); - listener.deleteRowNotifier.addPublishListener((result) { - result.fold((l) => null, (r) => null); - }); - listener.start(); } @@ -66,52 +58,42 @@ class GridBloc extends Bloc { final result = await service.openGrid(gridId: view.id); result.fold( (grid) { - _grid = grid; - }, - (err) { - emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))); + _loadFields(grid, emit); + emit(state.copyWith(grid: Some(grid))); }, + (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))), ); } - Future _loadFields(Emitter emit) async { - if (_grid != null) { - final result = await service.getFields(gridId: _grid!.id, fieldOrders: _grid!.fieldOrders); - result.fold( - (fields) { - _fields = fields.items; - }, - (err) { - emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))); - }, - ); - } + Future _loadFields(Grid grid, Emitter emit) async { + final result = await service.getFields(gridId: grid.id, fieldOrders: grid.fieldOrders); + result.fold( + (fields) { + _loadGridBlocks(grid, emit); + emit(state.copyWith(fields: fields.items)); + }, + (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))), + ); } - Future _loadGridInfo(Emitter emit) async { - final grid = _grid; - if (grid != null && _fields != null) { - final result = await service.getGridBlocks( - gridId: grid.id, - blocks: grid.blocks, - ); + Future _loadGridBlocks(Grid grid, Emitter emit) async { + final result = await service.getGridBlocks(gridId: grid.id, blocks: grid.blocks); - result.fold((repeatedGridBlock) { - final blocks = repeatedGridBlock.items; - final gridInfo = GridInfo( - gridId: grid.id, - blocks: blocks, - fields: _fields!, - ); - emit( - state.copyWith(loadingState: GridLoadingState.finish(left(unit)), gridInfo: some(left(gridInfo))), - ); - }, (err) { - emit( - state.copyWith(loadingState: GridLoadingState.finish(right(err)), gridInfo: none()), - ); - }); - } + result.fold((repeatedGridBlock) { + final blocks = repeatedGridBlock.items; + final gridInfo = GridInfo( + gridId: grid.id, + blocks: blocks, + fields: _fields!, + ); + emit( + state.copyWith(loadingState: GridLoadingState.finish(left(unit)), gridInfo: some(left(gridInfo))), + ); + }, (err) { + emit( + state.copyWith(loadingState: GridLoadingState.finish(right(err)), gridInfo: none()), + ); + }); } } @@ -128,12 +110,16 @@ abstract class GridEvent with _$GridEvent { abstract class GridState with _$GridState { const factory GridState({ required GridLoadingState loadingState, - required Option> gridInfo, + required List fields, + required List rows, + required Option grid, }) = _GridState; factory GridState.initial() => GridState( loadingState: const _Loading(), - gridInfo: none(), + fields: [], + rows: [], + grid: none(), ); } diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs index ba0396bf7f..82ab35bdee 100644 --- a/frontend/rust-lib/flowy-grid/src/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -6,6 +6,7 @@ const OBSERVABLE_CATEGORY: &str = "Grid"; pub enum GridNotification { Unknown = 0, GridDidUpdateBlock = 10, + GridDidCreateBlock = 11, GridDidUpdateCells = 20, GridDidUpdateFields = 30, 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 b3aa069170..95a0454eb1 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -187,7 +187,7 @@ pub struct GridBlock { pub block_id: String, #[pb(index = 2)] - pub rows: Vec, + pub rows: Vec, } impl GridBlock { From 05bcd38534b6479e9990fb786a44b4d717976c27 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 18 Mar 2022 17:14:46 +0800 Subject: [PATCH 27/28] chore: render rows --- .../lib/startup/home_deps_resolver.dart | 18 +- .../grid/cell_bloc/cell_service.dart | 13 +- .../lib/workspace/application/grid/data.dart | 43 - .../workspace/application/grid/grid_bloc.dart | 100 ++- ..._listener.dart => grid_block_service.dart} | 54 +- .../application/grid/grid_listenr.dart | 4 + .../application/grid/grid_service.dart | 24 +- .../workspace/application/grid/row_bloc.dart | 39 +- .../application/grid/row_service.dart | 28 +- .../plugins/grid/src/grid_page.dart | 34 +- .../src/widgets/content/cell_builder.dart | 17 +- .../src/widgets/content/checkbox_cell.dart | 8 +- .../grid/src/widgets/content/date_cell.dart | 8 +- .../grid/src/widgets/content/grid_row.dart | 29 +- .../grid/src/widgets/content/number_cell.dart | 8 +- .../src/widgets/content/selection_cell.dart | 4 +- .../grid/src/widgets/content/text_cell.dart | 8 +- .../dart_event/flowy-grid/dart_event.dart | 17 + .../flowy-error-code/code.pbenum.dart | 8 +- .../flowy-error-code/code.pbjson.dart | 7 +- .../flowy-grid-data-model/grid.pb.dart | 225 ++++- .../flowy-grid-data-model/grid.pbjson.dart | 50 +- .../flowy-grid-data-model/meta.pb.dart | 72 +- .../flowy-grid-data-model/meta.pbjson.dart | 20 +- .../flowy-grid/dart_notification.pbenum.dart | 2 + .../flowy-grid/dart_notification.pbjson.dart | 3 +- .../protobuf/flowy-grid/event_map.pbenum.dart | 8 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 9 +- frontend/rust-lib/Cargo.lock | 1 + frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- .../rust-lib/flowy-grid/src/event_handler.rs | 41 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 10 +- frontend/rust-lib/flowy-grid/src/manager.rs | 6 +- .../src/protobuf/model/dart_notification.rs | 10 +- .../src/protobuf/model/event_map.rs | 22 +- .../protobuf/proto/dart_notification.proto | 1 + .../src/protobuf/proto/event_map.proto | 7 +- .../src/services/block_meta_editor.rs | 70 +- .../flowy-grid/src/services/grid_editor.rs | 111 ++- .../flowy-grid/src/services/row/row_loader.rs | 40 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 40 +- shared-lib/Cargo.lock | 1 + ...eta_data_pad.rs => grid_block_meta_pad.rs} | 98 +- .../src/client_grid/grid_builder.rs | 14 +- .../src/client_grid/grid_meta_pad.rs | 16 +- .../src/client_grid/mod.rs | 4 +- shared-lib/flowy-error-code/src/code.rs | 8 +- .../src/protobuf/model/code.rs | 20 +- .../src/protobuf/proto/code.proto | 5 +- shared-lib/flowy-grid-data-model/Cargo.toml | 1 + .../src/entities/grid.rs | 48 +- .../src/entities/meta.rs | 17 +- shared-lib/flowy-grid-data-model/src/lib.rs | 1 + .../flowy-grid-data-model/src/parser/grid.rs | 82 ++ .../flowy-grid-data-model/src/parser/id.rs | 20 + .../flowy-grid-data-model/src/parser/mod.rs | 5 + .../src/protobuf/model/grid.rs | 843 +++++++++++++++--- .../src/protobuf/model/meta.rs | 225 +++-- .../src/protobuf/proto/grid.proto | 19 +- .../src/protobuf/proto/meta.proto | 8 +- .../flowy-grid-data-model/tests/serde_test.rs | 4 +- 61 files changed, 1884 insertions(+), 778 deletions(-) rename frontend/app_flowy/lib/workspace/application/grid/{grid_listener.dart => grid_block_service.dart} (55%) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart rename shared-lib/flowy-collaboration/src/client_grid/{grid_block_meta_data_pad.rs => grid_block_meta_pad.rs} (79%) create mode 100644 shared-lib/flowy-grid-data-model/src/parser/grid.rs create mode 100644 shared-lib/flowy-grid-data-model/src/parser/id.rs create mode 100644 shared-lib/flowy-grid-data-model/src/parser/mod.rs diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index 084612ca61..2dcf6ca077 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -17,8 +17,6 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:get_it/get_it.dart'; -import '../workspace/application/grid/grid_listener.dart'; - class HomeDepsResolver { static Future resolve(GetIt getIt) async { getIt.registerFactoryParam( @@ -93,13 +91,13 @@ class HomeDepsResolver { // Grid getIt.registerFactoryParam( - (view, _) => GridBloc(view: view, service: GridService(), listener: GridListener(gridId: view.id)), + (view, _) => GridBloc(view: view, service: GridService()), ); getIt.registerFactoryParam( (data, _) => RowBloc( - service: RowService(data), - listener: RowListener(rowId: data.row.id), + rowService: RowService(data), + listener: RowListener(rowId: data.rowId), ), ); @@ -110,31 +108,31 @@ class HomeDepsResolver { ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (context, _) => TextCellBloc( service: CellService(context), ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (context, _) => SelectionCellBloc( service: CellService(context), ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (context, _) => NumberCellBloc( service: CellService(context), ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (context, _) => DateCellBloc( service: CellService(context), ), ); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (context, _) => CheckboxCellBloc( service: CellService(context), ), diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart index 456615220d..44cf86e5d2 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -1,11 +1,11 @@ +import 'package:app_flowy/workspace/application/grid/row_service.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; class CellService { - final CellContext context; + final GridCellData context; CellService(this.context); @@ -18,12 +18,3 @@ class CellService { return GridEventUpdateCell(payload).send(); } } - -class CellContext { - final String gridId; - final String rowId; - final Field field; - final Cell? cell; - - CellContext({required this.rowId, required this.gridId, required this.field, required this.cell}); -} diff --git a/frontend/app_flowy/lib/workspace/application/grid/data.dart b/frontend/app_flowy/lib/workspace/application/grid/data.dart index 05ca053b8c..ff1b1e3efc 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/data.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/data.dart @@ -1,47 +1,4 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'package:equatable/equatable.dart'; - -class GridInfo { - final String gridId; - List gridBlocks; - List fields; - - GridInfo({ - required this.gridId, - required this.gridBlocks, - required this.fields, - }); - - GridRowData rowAtIndex(int index) { - final row = rows[index]; - return GridRowData( - gridId: gridId, - row: row, - fields: fields, - cellMap: row.cellByFieldId, - ); - } - - int numberOfRows() { - return rows.length; - } -} - -class GridRowData extends Equatable { - final String gridId; - final Row row; - final List fields; - final Map cellMap; - const GridRowData({ - required this.gridId, - required this.row, - required this.fields, - required this.cellMap, - }); - - @override - List get props => [row.hashCode, cellMap]; -} class GridColumnData { final List fields; diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart index b5e6cc67d5..1db06d815c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -1,14 +1,12 @@ import 'dart:async'; - import 'package:dartz/dartz.dart'; -import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -import 'data.dart'; -import 'grid_listener.dart'; +import 'grid_block_service.dart'; +import 'grid_listenr.dart'; import 'grid_service.dart'; part 'grid_bloc.freezed.dart'; @@ -16,14 +14,16 @@ part 'grid_bloc.freezed.dart'; class GridBloc extends Bloc { final View view; final GridService service; - final GridListener listener; + late GridListener _gridListener; + late GridBlockService _blockService; + + GridBloc({required this.view, required this.service}) : super(GridState.initial()) { + _gridListener = GridListener(); - GridBloc({required this.view, required this.service, required this.listener}) : super(GridState.initial()) { on( (event, emit) async { await event.map( initial: (InitialGrid value) async { - await _startGridListening(); await _loadGrid(emit); }, createRow: (_CreateRow value) { @@ -32,6 +32,9 @@ class GridBloc extends Bloc { delete: (_Delete value) {}, rename: (_Rename value) {}, updateDesc: (_Desc value) {}, + didLoadRows: (_DidLoadRows value) { + emit(state.copyWith(rows: value.rows)); + }, ); }, ); @@ -39,61 +42,63 @@ class GridBloc extends Bloc { @override Future close() async { - await listener.close(); + await _gridListener.stop(); + await _blockService.stop(); return super.close(); } Future _startGridListening() async { - listener.blockUpdateNotifier.addPublishListener((result) { - result.fold((blockId) { - // - Log.info("$blockId"); - }, (err) => null); - }); + _blockService.didLoadRowscallback = (rows) { + add(GridEvent.didLoadRows(rows)); + }; - listener.start(); + _gridListener.start(); } Future _loadGrid(Emitter emit) async { final result = await service.openGrid(gridId: view.id); - result.fold( - (grid) { - _loadFields(grid, emit); - emit(state.copyWith(grid: Some(grid))); - }, - (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))), + + return Future( + () => result.fold( + (grid) async => await _loadFields(grid, emit), + (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))), + ), ); } Future _loadFields(Grid grid, Emitter emit) async { final result = await service.getFields(gridId: grid.id, fieldOrders: grid.fieldOrders); - result.fold( - (fields) { - _loadGridBlocks(grid, emit); - emit(state.copyWith(fields: fields.items)); - }, - (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))), + return Future( + () => result.fold( + (fields) => _loadGridBlocks(grid, fields.items, emit), + (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))), + ), ); } - Future _loadGridBlocks(Grid grid, Emitter emit) async { - final result = await service.getGridBlocks(gridId: grid.id, blocks: grid.blocks); + Future _loadGridBlocks(Grid grid, List fields, Emitter emit) async { + final result = await service.getGridBlocks(gridId: grid.id, blockOrders: grid.blockOrders); + result.fold( + (repeatedGridBlock) { + final gridBlocks = repeatedGridBlock.items; + final gridId = view.id; + _blockService = GridBlockService( + gridId: gridId, + fields: fields, + gridBlocks: gridBlocks, + ); + final rows = _blockService.rows(); - result.fold((repeatedGridBlock) { - final blocks = repeatedGridBlock.items; - final gridInfo = GridInfo( - gridId: grid.id, - blocks: blocks, - fields: _fields!, - ); - emit( - state.copyWith(loadingState: GridLoadingState.finish(left(unit)), gridInfo: some(left(gridInfo))), - ); - }, (err) { - emit( - state.copyWith(loadingState: GridLoadingState.finish(right(err)), gridInfo: none()), - ); - }); + _startGridListening(); + emit(state.copyWith( + grid: Some(grid), + fields: Some(fields), + rows: rows, + loadingState: GridLoadingState.finish(left(unit)), + )); + }, + (err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)), rows: [])), + ); } } @@ -104,20 +109,21 @@ abstract class GridEvent with _$GridEvent { const factory GridEvent.updateDesc(String gridId, String desc) = _Desc; const factory GridEvent.delete(String gridId) = _Delete; const factory GridEvent.createRow() = _CreateRow; + const factory GridEvent.didLoadRows(List rows) = _DidLoadRows; } @freezed abstract class GridState with _$GridState { const factory GridState({ required GridLoadingState loadingState, - required List fields, - required List rows, + required Option> fields, + required List rows, required Option grid, }) = _GridState; factory GridState.initial() => GridState( loadingState: const _Loading(), - fields: [], + fields: none(), rows: [], grid: none(), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart similarity index 55% rename from frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart rename to frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart index 67f69b57b6..973f412e9e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart @@ -1,23 +1,67 @@ +import 'dart:collection'; +import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; import 'package:flowy_sdk/rust_stream.dart'; import 'package:flowy_infra/notifier.dart'; import 'dart:async'; import 'dart:typed_data'; import 'package:app_flowy/core/notification_helper.dart'; -import 'package:dartz/dartz.dart'; +import 'grid_service.dart'; + +typedef DidLoadRowsCallback = void Function(List); typedef GridBlockUpdateNotifiedValue = Either; -class GridListener { +class GridBlockService { + String gridId; + List fields; + LinkedHashMap blockMap = LinkedHashMap(); + late GridBlockListener _blockListener; + DidLoadRowsCallback? didLoadRowscallback; + + GridBlockService({required this.gridId, required this.fields, required List gridBlocks}) { + for (final gridBlock in gridBlocks) { + blockMap[gridBlock.blockId] = gridBlock; + } + + _blockListener = GridBlockListener(gridId: gridId); + _blockListener.blockUpdateNotifier.addPublishListener((result) { + result.fold((blockId) { + // + }, (err) => null); + }); + } + + List rows() { + List rows = []; + blockMap.forEach((_, gridBlock) { + rows.addAll(gridBlock.rowIds.map( + (rowId) => GridRowData( + gridId: gridId, + fields: fields, + blockId: gridBlock.blockId, + rowId: rowId, + ), + )); + }); + return rows; + } + + Future stop() async { + await _blockListener.stop(); + } +} + +class GridBlockListener { final String gridId; PublishNotifier blockUpdateNotifier = PublishNotifier(); StreamSubscription? _subscription; late GridNotificationParser _parser; - GridListener({required this.gridId}); + GridBlockListener({required this.gridId}); void start() { _parser = GridNotificationParser( @@ -44,7 +88,7 @@ class GridListener { } } - Future close() async { + Future stop() async { await _subscription?.cancel(); blockUpdateNotifier.dispose(); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart new file mode 100644 index 0000000000..55e29d915c --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_listenr.dart @@ -0,0 +1,4 @@ +class GridListener { + void start() {} + Future stop() async {} +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index 62208c8d05..976860029e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -3,7 +3,7 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:dartz/dartz.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:equatable/equatable.dart'; class GridService { Future> openGrid({required String gridId}) async { @@ -15,15 +15,15 @@ class GridService { Future> createRow({required String gridId, Option? upperRowId}) { CreateRowPayload payload = CreateRowPayload.create()..gridId = gridId; - upperRowId?.fold(() => null, (id) => payload.upperRowId = id); + upperRowId?.fold(() => null, (id) => payload.startRowId = id); return GridEventCreateRow(payload).send(); } Future> getGridBlocks( - {required String gridId, required List blocks}) { + {required String gridId, required List blockOrders}) { final payload = QueryGridBlocksPayload.create() ..gridId = gridId - ..blocks.addAll(blocks); + ..blockOrders.addAll(blockOrders); return GridEventGetGridBlocks(payload).send(); } @@ -34,3 +34,19 @@ class GridService { return GridEventGetFields(payload).send(); } } + +class GridRowData extends Equatable { + final String gridId; + final String rowId; + final String blockId; + final List fields; + const GridRowData({ + required this.gridId, + required this.rowId, + required this.blockId, + required this.fields, + }); + + @override + List get props => [rowId]; +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart index 16195af592..32525a1bb7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart @@ -2,25 +2,26 @@ import 'package:flowy_sdk/log.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; -import 'data.dart'; +import 'grid_service.dart'; import 'row_listener.dart'; import 'row_service.dart'; part 'row_bloc.freezed.dart'; class RowBloc extends Bloc { - final RowService service; + final RowService rowService; final RowListener listener; - RowBloc({required this.service, required this.listener}) : super(RowState.initial(service.rowData)) { + RowBloc({required this.rowService, required this.listener}) : super(RowState.initial(rowService.rowData)) { on( (event, emit) async { await event.map( initial: (_InitialRow value) async { _startRowListening(); + await _loadCellDatas(emit); }, createRow: (_CreateRow value) { - service.createRow(); + rowService.createRow(); }, activeRow: (_ActiveRow value) { emit(state.copyWith(active: true)); @@ -55,6 +56,25 @@ class RowBloc extends Bloc { listener.start(); } + + Future _loadCellDatas(Emitter emit) async { + final result = await rowService.getRow(); + result.fold( + (row) { + final cellDatas = rowService.rowData.fields.map((field) { + final cell = row.cellByFieldId[field.id]; + return GridCellData( + rowId: row.id, + gridId: rowService.rowData.gridId, + cell: cell, + field: field, + ); + }).toList(); + emit(state.copyWith(cellDatas: cellDatas, rowHeight: row.height.toDouble())); + }, + (e) => Log.error(e), + ); + } } @freezed @@ -68,9 +88,16 @@ abstract class RowEvent with _$RowEvent { @freezed abstract class RowState with _$RowState { const factory RowState({ - required GridRowData data, + required String rowId, + required double rowHeight, + required List cellDatas, required bool active, }) = _RowState; - factory RowState.initial(GridRowData data) => RowState(data: data, active: false); + factory RowState.initial(GridRowData data) => RowState( + rowId: data.rowId, + active: false, + rowHeight: 0, + cellDatas: [], + ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart index 03d732f862..986442c47e 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart @@ -1,9 +1,10 @@ -import 'package:app_flowy/workspace/application/grid/data.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'grid_service.dart'; + class RowService { final GridRowData rowData; @@ -12,8 +13,31 @@ class RowService { Future> createRow() { CreateRowPayload payload = CreateRowPayload.create() ..gridId = rowData.gridId - ..upperRowId = rowData.row.id; + ..startRowId = rowData.rowId; return GridEventCreateRow(payload).send(); } + + Future> getRow() { + QueryRowPayload payload = QueryRowPayload.create() + ..gridId = rowData.gridId + ..blockId = rowData.blockId + ..rowId = rowData.rowId; + + return GridEventGetRow(payload).send(); + } +} + +class GridCellData { + final String gridId; + final String rowId; + final Field field; + final Cell? cell; + + GridCellData({ + required this.rowId, + required this.gridId, + required this.field, + required this.cell, + }); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index c396e7d71f..4e7747ac1d 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -1,5 +1,4 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/data.dart'; import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart'; @@ -41,7 +40,7 @@ class _GridPageState extends State { return state.loadingState.map( loading: (_) => const Center(child: CircularProgressIndicator.adaptive()), finish: (result) => result.successOrFail.fold( - (_) => const GridBody(), + (_) => const FlowyGrid(), (err) => FlowyErrorPage(err.toString()), ), ); @@ -66,14 +65,14 @@ class _GridPageState extends State { } } -class GridBody extends StatefulWidget { - const GridBody({Key? key}) : super(key: key); +class FlowyGrid extends StatefulWidget { + const FlowyGrid({Key? key}) : super(key: key); @override - _GridBodyState createState() => _GridBodyState(); + _FlowyGridState createState() => _FlowyGridState(); } -class _GridBodyState extends State { +class _FlowyGridState extends State { final _scrollController = GridScrollController(); @override @@ -86,31 +85,28 @@ class _GridBodyState extends State { Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { - return state.gridInfo.fold( + return state.fields.fold( () => const Center(child: CircularProgressIndicator.adaptive()), - (some) => some.fold( - (gridInfo) => _renderGrid(context, gridInfo), - (err) => FlowyErrorPage(err.toString()), - ), + (fields) => _renderGrid(context, fields), ); }, ); } - Widget _renderGrid(BuildContext context, GridInfo gridInfo) { + Widget _renderGrid(BuildContext context, List fields) { return Stack( children: [ StyledSingleChildScrollView( controller: _scrollController.horizontalController, axis: Axis.horizontal, child: SizedBox( - width: GridLayout.headerWidth(gridInfo.fields), + width: GridLayout.headerWidth(fields), child: CustomScrollView( physics: StyledScrollPhysics(), controller: _scrollController.verticalController, slivers: [ - _buildHeader(gridInfo.fields), - _buildRows(gridInfo), + _buildHeader(fields), + _buildRows(context), const GridFooter(), ], ), @@ -134,14 +130,14 @@ class _GridBodyState extends State { ); } - Widget _buildRows(GridInfo gridInfo) { + Widget _buildRows(BuildContext context) { return SliverList( delegate: SliverChildBuilderDelegate( (context, index) { - final data = gridInfo.rowAtIndex(index); - return GridRowWidget(data: data); + final rowData = context.read().state.rows[index]; + return GridRowWidget(data: rowData); }, - childCount: gridInfo.numberOfRows(), + childCount: context.read().state.rows.length, addRepaintBoundaries: true, ), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index 7b183abbe5..2bb1782f13 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -1,4 +1,5 @@ import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; +import 'package:app_flowy/workspace/application/grid/row_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; import 'checkbox_cell.dart'; @@ -7,20 +8,20 @@ import 'number_cell.dart'; import 'selection_cell.dart'; import 'text_cell.dart'; -Widget buildGridCell(CellContext cellContext) { - switch (cellContext.field.fieldType) { +Widget buildGridCell(GridCellData cellData) { + switch (cellData.field.fieldType) { case FieldType.Checkbox: - return CheckboxCell(cellContext: cellContext); + return CheckboxCell(cellData: cellData); case FieldType.DateTime: - return DateCell(cellContext: cellContext); + return DateCell(cellData: cellData); case FieldType.MultiSelect: - return MultiSelectCell(cellContext: cellContext); + return MultiSelectCell(cellContext: cellData); case FieldType.Number: - return NumberCell(cellContext: cellContext); + return NumberCell(cellData: cellData); case FieldType.RichText: - return GridTextCell(cellContext: cellContext); + return GridTextCell(cellData: cellData); case FieldType.SingleSelect: - return SingleSelectCell(cellContext: cellContext); + return SingleSelectCell(cellContext: cellData); default: return const BlankCell(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart index ec3e51b102..eec381914a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/checkbox_cell.dart @@ -1,14 +1,14 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/row_service.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class CheckboxCell extends StatefulWidget { - final CellContext cellContext; + final GridCellData cellData; const CheckboxCell({ - required this.cellContext, + required this.cellData, Key? key, }) : super(key: key); @@ -21,7 +21,7 @@ class _CheckboxCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.cellContext); + _cellBloc = getIt(param1: widget.cellData); super.initState(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart index dbe631f2f1..5d9f452c78 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/date_cell.dart @@ -1,14 +1,14 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/date_cell_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/row_service.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class DateCell extends StatefulWidget { - final CellContext cellContext; + final GridCellData cellData; const DateCell({ - required this.cellContext, + required this.cellData, Key? key, }) : super(key: key); @@ -21,7 +21,7 @@ class _DateCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.cellContext); + _cellBloc = getIt(param1: widget.cellData); super.initState(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index c8bd05c3fe..45f5f89c38 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -11,7 +11,7 @@ import 'cell_container.dart'; class GridRowWidget extends StatefulWidget { final GridRowData data; - GridRowWidget({required this.data, Key? key}) : super(key: ObjectKey(data.row.id)); + GridRowWidget({required this.data, Key? key}) : super(key: ObjectKey(data.rowId)); @override State createState() => _GridRowWidgetState(); @@ -37,7 +37,7 @@ class _GridRowWidgetState extends State { onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), child: SizedBox( - height: _rowBloc.state.data.row.height.toDouble(), + height: _rowBloc.state.rowHeight, child: Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ @@ -60,26 +60,17 @@ class _GridRowWidgetState extends State { Widget _buildCells() { return BlocBuilder( - buildWhen: (p, c) => p.data != c.data, + buildWhen: (p, c) => p.cellDatas != c.cellDatas, builder: (context, state) { return Row( - key: ValueKey(state.data.row.id), - children: state.data.fields.map( - (field) { - final cell = state.data.cellMap[field.id]; - return CellContainer( - width: field.width.toDouble(), - child: buildGridCell( - CellContext( - gridId: state.data.gridId, - rowId: state.data.row.id, - field: field, - cell: cell, - ), + children: state.cellDatas + .map( + (cellData) => CellContainer( + width: cellData.field.width.toDouble(), + child: buildGridCell(cellData), ), - ); - }, - ).toList(), + ) + .toList(), ); }, ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart index c624618ec7..ea3f70fed3 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/number_cell.dart @@ -1,14 +1,14 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/number_cell_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/row_service.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class NumberCell extends StatefulWidget { - final CellContext cellContext; + final GridCellData cellData; const NumberCell({ - required this.cellContext, + required this.cellData, Key? key, }) : super(key: key); @@ -21,7 +21,7 @@ class _NumberCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.cellContext); + _cellBloc = getIt(param1: widget.cellData); super.initState(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart index 575815013d..94891924cd 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/selection_cell.dart @@ -3,7 +3,7 @@ import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:flutter/material.dart'; class SingleSelectCell extends StatefulWidget { - final CellContext cellContext; + final GridCellData cellContext; const SingleSelectCell({ required this.cellContext, @@ -37,7 +37,7 @@ class _SingleSelectCellState extends State { //---------------------------------------------------------------- class MultiSelectCell extends StatefulWidget { - final CellContext cellContext; + final GridCellData cellContext; const MultiSelectCell({ required this.cellContext, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart index c5c330616b..71ab0c41bd 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/text_cell.dart @@ -1,15 +1,15 @@ import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/row_service.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; /// The interface of base cell. class GridTextCell extends StatefulWidget { - final CellContext cellContext; + final GridCellData cellData; const GridTextCell({ - required this.cellContext, + required this.cellData, Key? key, }) : super(key: key); @@ -24,7 +24,7 @@ class _GridTextCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.cellContext); + _cellBloc = getIt(param1: widget.cellData); _controller = TextEditingController(text: _cellBloc.state.content); _focusNode.addListener(_focusChanged); super.initState(); 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 10cb8bae79..c13b12e687 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 @@ -69,6 +69,23 @@ class GridEventCreateRow { } } +class GridEventGetRow { + QueryRowPayload request; + GridEventGetRow(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.GetRow.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (okBytes) => left(Row.fromBuffer(okBytes)), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + class GridEventUpdateCell { CellMetaChangeset request; GridEventUpdateCell(this.request); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart index 69efeb81b7..02e3e595c5 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart @@ -41,7 +41,10 @@ class ErrorCode extends $pb.ProtobufEnum { static const ErrorCode UserIdInvalid = ErrorCode._(311, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdInvalid'); static const ErrorCode UserNotExist = ErrorCode._(312, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotExist'); static const ErrorCode TextTooLong = ErrorCode._(400, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TextTooLong'); - static const ErrorCode InvalidData = ErrorCode._(401, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidData'); + static const ErrorCode BlockIdIsEmpty = ErrorCode._(401, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BlockIdIsEmpty'); + static const ErrorCode RowIdIsEmpty = ErrorCode._(402, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RowIdIsEmpty'); + static const ErrorCode GridIdIsEmpty = ErrorCode._(403, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridIdIsEmpty'); + static const ErrorCode InvalidData = ErrorCode._(404, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidData'); static const $core.List values = [ Internal, @@ -75,6 +78,9 @@ class ErrorCode extends $pb.ProtobufEnum { UserIdInvalid, UserNotExist, TextTooLong, + BlockIdIsEmpty, + RowIdIsEmpty, + GridIdIsEmpty, InvalidData, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart index 26a0b31029..7a3269aa7f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart @@ -43,9 +43,12 @@ const ErrorCode$json = const { const {'1': 'UserIdInvalid', '2': 311}, const {'1': 'UserNotExist', '2': 312}, const {'1': 'TextTooLong', '2': 400}, - const {'1': 'InvalidData', '2': 401}, + const {'1': 'BlockIdIsEmpty', '2': 401}, + const {'1': 'RowIdIsEmpty', '2': 402}, + const {'1': 'GridIdIsEmpty', '2': 403}, + const {'1': 'InvalidData', '2': 404}, ], }; /// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIYChRXb3Jrc3BhY2VOYW1lSW52YWxpZBBkEhYKEldvcmtzcGFjZUlkSW52YWxpZBBlEhgKFEFwcENvbG9yU3R5bGVJbnZhbGlkEGYSGAoUV29ya3NwYWNlRGVzY1Rvb0xvbmcQZxIYChRXb3Jrc3BhY2VOYW1lVG9vTG9uZxBoEhAKDEFwcElkSW52YWxpZBBuEhIKDkFwcE5hbWVJbnZhbGlkEG8SEwoPVmlld05hbWVJbnZhbGlkEHgSGAoUVmlld1RodW1ibmFpbEludmFsaWQQeRIRCg1WaWV3SWRJbnZhbGlkEHoSEwoPVmlld0Rlc2NUb29Mb25nEHsSEwoPVmlld0RhdGFJbnZhbGlkEHwSEwoPVmlld05hbWVUb29Mb25nEH0SEQoMQ29ubmVjdEVycm9yEMgBEhEKDEVtYWlsSXNFbXB0eRCsAhIXChJFbWFpbEZvcm1hdEludmFsaWQQrQISFwoSRW1haWxBbHJlYWR5RXhpc3RzEK4CEhQKD1Bhc3N3b3JkSXNFbXB0eRCvAhIUCg9QYXNzd29yZFRvb0xvbmcQsAISJQogUGFzc3dvcmRDb250YWluc0ZvcmJpZENoYXJhY3RlcnMQsQISGgoVUGFzc3dvcmRGb3JtYXRJbnZhbGlkELICEhUKEFBhc3N3b3JkTm90TWF0Y2gQswISFAoPVXNlck5hbWVUb29Mb25nELQCEicKIlVzZXJOYW1lQ29udGFpbkZvcmJpZGRlbkNoYXJhY3RlcnMQtQISFAoPVXNlck5hbWVJc0VtcHR5ELYCEhIKDVVzZXJJZEludmFsaWQQtwISEQoMVXNlck5vdEV4aXN0ELgCEhAKC1RleHRUb29Mb25nEJADEhAKC0ludmFsaWREYXRhEJED'); +final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIYChRXb3Jrc3BhY2VOYW1lSW52YWxpZBBkEhYKEldvcmtzcGFjZUlkSW52YWxpZBBlEhgKFEFwcENvbG9yU3R5bGVJbnZhbGlkEGYSGAoUV29ya3NwYWNlRGVzY1Rvb0xvbmcQZxIYChRXb3Jrc3BhY2VOYW1lVG9vTG9uZxBoEhAKDEFwcElkSW52YWxpZBBuEhIKDkFwcE5hbWVJbnZhbGlkEG8SEwoPVmlld05hbWVJbnZhbGlkEHgSGAoUVmlld1RodW1ibmFpbEludmFsaWQQeRIRCg1WaWV3SWRJbnZhbGlkEHoSEwoPVmlld0Rlc2NUb29Mb25nEHsSEwoPVmlld0RhdGFJbnZhbGlkEHwSEwoPVmlld05hbWVUb29Mb25nEH0SEQoMQ29ubmVjdEVycm9yEMgBEhEKDEVtYWlsSXNFbXB0eRCsAhIXChJFbWFpbEZvcm1hdEludmFsaWQQrQISFwoSRW1haWxBbHJlYWR5RXhpc3RzEK4CEhQKD1Bhc3N3b3JkSXNFbXB0eRCvAhIUCg9QYXNzd29yZFRvb0xvbmcQsAISJQogUGFzc3dvcmRDb250YWluc0ZvcmJpZENoYXJhY3RlcnMQsQISGgoVUGFzc3dvcmRGb3JtYXRJbnZhbGlkELICEhUKEFBhc3N3b3JkTm90TWF0Y2gQswISFAoPVXNlck5hbWVUb29Mb25nELQCEicKIlVzZXJOYW1lQ29udGFpbkZvcmJpZGRlbkNoYXJhY3RlcnMQtQISFAoPVXNlck5hbWVJc0VtcHR5ELYCEhIKDVVzZXJJZEludmFsaWQQtwISEQoMVXNlck5vdEV4aXN0ELgCEhAKC1RleHRUb29Mb25nEJADEhMKDkJsb2NrSWRJc0VtcHR5EJEDEhEKDFJvd0lkSXNFbXB0eRCSAxISCg1HcmlkSWRJc0VtcHR5EJMDEhAKC0ludmFsaWREYXRhEJQD'); 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 9b4dc19b7c..b44a3e7814 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 @@ -9,15 +9,13 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; -import 'meta.pb.dart' as $0; - import 'meta.pbenum.dart' as $0; class Grid extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Grid', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', $pb.PbFieldType.PM, subBuilder: FieldOrder.create) - ..pc<$0.GridBlockMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: $0.GridBlockMeta.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockOrders', $pb.PbFieldType.PM, subBuilder: GridBlockOrder.create) ..hasRequiredFields = false ; @@ -25,7 +23,7 @@ class Grid extends $pb.GeneratedMessage { factory Grid({ $core.String? id, $core.Iterable? fieldOrders, - $core.Iterable<$0.GridBlockMeta>? blocks, + $core.Iterable? blockOrders, }) { final _result = create(); if (id != null) { @@ -34,8 +32,8 @@ class Grid extends $pb.GeneratedMessage { if (fieldOrders != null) { _result.fieldOrders.addAll(fieldOrders); } - if (blocks != null) { - _result.blocks.addAll(blocks); + if (blockOrders != null) { + _result.blockOrders.addAll(blockOrders); } return _result; } @@ -73,7 +71,7 @@ class Grid extends $pb.GeneratedMessage { $core.List get fieldOrders => $_getList(1); @$pb.TagNumber(3) - $core.List<$0.GridBlockMeta> get blocks => $_getList(2); + $core.List get blockOrders => $_getList(2); } class Field extends $pb.GeneratedMessage { @@ -507,6 +505,47 @@ class Row extends $pb.GeneratedMessage { void clearHeight() => clearField(3); } +class RepeatedRow extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedRow', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Row.create) + ..hasRequiredFields = false + ; + + RepeatedRow._() : super(); + factory RepeatedRow({ + $core.Iterable? items, + }) { + final _result = create(); + if (items != null) { + _result.items.addAll(items); + } + return _result; + } + factory RepeatedRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedRow.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RepeatedRow clone() => RepeatedRow()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RepeatedRow copyWith(void Function(RepeatedRow) updates) => super.copyWith((message) => updates(message as RepeatedRow)) as RepeatedRow; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RepeatedRow create() => RepeatedRow._(); + RepeatedRow createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RepeatedRow getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedRow? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get items => $_getList(0); +} + class RepeatedGridBlock extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedGridBlock', createEmptyInstance: create) ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: GridBlock.create) @@ -548,24 +587,71 @@ class RepeatedGridBlock extends $pb.GeneratedMessage { $core.List get items => $_getList(0); } +class GridBlockOrder extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockOrder', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..hasRequiredFields = false + ; + + GridBlockOrder._() : super(); + factory GridBlockOrder({ + $core.String? blockId, + }) { + final _result = create(); + if (blockId != null) { + _result.blockId = blockId; + } + return _result; + } + factory GridBlockOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlockOrder.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + GridBlockOrder clone() => GridBlockOrder()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridBlockOrder copyWith(void Function(GridBlockOrder) updates) => super.copyWith((message) => updates(message as GridBlockOrder)) as GridBlockOrder; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridBlockOrder create() => GridBlockOrder._(); + GridBlockOrder createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridBlockOrder getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlockOrder? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get blockId => $_getSZ(0); + @$pb.TagNumber(1) + set blockId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasBlockId() => $_has(0); + @$pb.TagNumber(1) + void clearBlockId() => clearField(1); +} + class GridBlock extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') - ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: Row.create) + ..pPS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowIds') ..hasRequiredFields = false ; GridBlock._() : super(); factory GridBlock({ $core.String? blockId, - $core.Iterable? rows, + $core.Iterable<$core.String>? rowIds, }) { final _result = create(); if (blockId != null) { _result.blockId = blockId; } - if (rows != null) { - _result.rows.addAll(rows); + if (rowIds != null) { + _result.rowIds.addAll(rowIds); } return _result; } @@ -600,7 +686,7 @@ class GridBlock extends $pb.GeneratedMessage { void clearBlockId() => clearField(1); @$pb.TagNumber(2) - $core.List get rows => $_getList(1); + $core.List<$core.String> get rowIds => $_getList(1); } class Cell extends $pb.GeneratedMessage { @@ -846,34 +932,34 @@ class GridBlockId extends $pb.GeneratedMessage { void clearValue() => clearField(1); } -enum CreateRowPayload_OneOfUpperRowId { - upperRowId, +enum CreateRowPayload_OneOfStartRowId { + startRowId, notSet } class CreateRowPayload extends $pb.GeneratedMessage { - static const $core.Map<$core.int, CreateRowPayload_OneOfUpperRowId> _CreateRowPayload_OneOfUpperRowIdByTag = { - 2 : CreateRowPayload_OneOfUpperRowId.upperRowId, - 0 : CreateRowPayload_OneOfUpperRowId.notSet + static const $core.Map<$core.int, CreateRowPayload_OneOfStartRowId> _CreateRowPayload_OneOfStartRowIdByTag = { + 2 : CreateRowPayload_OneOfStartRowId.startRowId, + 0 : CreateRowPayload_OneOfStartRowId.notSet }; static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateRowPayload', createEmptyInstance: create) ..oo(0, [2]) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'upperRowId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startRowId') ..hasRequiredFields = false ; CreateRowPayload._() : super(); factory CreateRowPayload({ $core.String? gridId, - $core.String? upperRowId, + $core.String? startRowId, }) { final _result = create(); if (gridId != null) { _result.gridId = gridId; } - if (upperRowId != null) { - _result.upperRowId = upperRowId; + if (startRowId != null) { + _result.startRowId = startRowId; } return _result; } @@ -898,8 +984,8 @@ class CreateRowPayload extends $pb.GeneratedMessage { static CreateRowPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); static CreateRowPayload? _defaultInstance; - CreateRowPayload_OneOfUpperRowId whichOneOfUpperRowId() => _CreateRowPayload_OneOfUpperRowIdByTag[$_whichOneof(0)]!; - void clearOneOfUpperRowId() => clearField($_whichOneof(0)); + CreateRowPayload_OneOfStartRowId whichOneOfStartRowId() => _CreateRowPayload_OneOfStartRowIdByTag[$_whichOneof(0)]!; + void clearOneOfStartRowId() => clearField($_whichOneof(0)); @$pb.TagNumber(1) $core.String get gridId => $_getSZ(0); @@ -911,13 +997,13 @@ class CreateRowPayload extends $pb.GeneratedMessage { void clearGridId() => clearField(1); @$pb.TagNumber(2) - $core.String get upperRowId => $_getSZ(1); + $core.String get startRowId => $_getSZ(1); @$pb.TagNumber(2) - set upperRowId($core.String v) { $_setString(1, v); } + set startRowId($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasUpperRowId() => $_has(1); + $core.bool hasStartRowId() => $_has(1); @$pb.TagNumber(2) - void clearUpperRowId() => clearField(2); + void clearStartRowId() => clearField(2); } class QueryFieldPayload extends $pb.GeneratedMessage { @@ -986,21 +1072,21 @@ class QueryFieldPayload extends $pb.GeneratedMessage { class QueryGridBlocksPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryGridBlocksPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..pc<$0.GridBlockMeta>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: $0.GridBlockMeta.create) + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockOrders', $pb.PbFieldType.PM, subBuilder: GridBlockOrder.create) ..hasRequiredFields = false ; QueryGridBlocksPayload._() : super(); factory QueryGridBlocksPayload({ $core.String? gridId, - $core.Iterable<$0.GridBlockMeta>? blocks, + $core.Iterable? blockOrders, }) { final _result = create(); if (gridId != null) { _result.gridId = gridId; } - if (blocks != null) { - _result.blocks.addAll(blocks); + if (blockOrders != null) { + _result.blockOrders.addAll(blockOrders); } return _result; } @@ -1035,6 +1121,81 @@ class QueryGridBlocksPayload extends $pb.GeneratedMessage { void clearGridId() => clearField(1); @$pb.TagNumber(2) - $core.List<$0.GridBlockMeta> get blocks => $_getList(1); + $core.List get blockOrders => $_getList(1); +} + +class QueryRowPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryRowPayload', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..hasRequiredFields = false + ; + + QueryRowPayload._() : super(); + factory QueryRowPayload({ + $core.String? gridId, + $core.String? blockId, + $core.String? rowId, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (blockId != null) { + _result.blockId = blockId; + } + if (rowId != null) { + _result.rowId = rowId; + } + return _result; + } + factory QueryRowPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory QueryRowPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + QueryRowPayload clone() => QueryRowPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + QueryRowPayload copyWith(void Function(QueryRowPayload) updates) => super.copyWith((message) => updates(message as QueryRowPayload)) as QueryRowPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static QueryRowPayload create() => QueryRowPayload._(); + QueryRowPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static QueryRowPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static QueryRowPayload? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get gridId => $_getSZ(0); + @$pb.TagNumber(1) + set gridId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasGridId() => $_has(0); + @$pb.TagNumber(1) + void clearGridId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get blockId => $_getSZ(1); + @$pb.TagNumber(2) + set blockId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasBlockId() => $_has(1); + @$pb.TagNumber(2) + void clearBlockId() => clearField(2); + + @$pb.TagNumber(3) + $core.String get rowId => $_getSZ(2); + @$pb.TagNumber(3) + set rowId($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasRowId() => $_has(2); + @$pb.TagNumber(3) + void clearRowId() => clearField(3); } 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 97d52d827f..c4d79ccb0b 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 @@ -14,12 +14,12 @@ const Grid$json = const { '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'field_orders', '3': 2, '4': 3, '5': 11, '6': '.FieldOrder', '10': 'fieldOrders'}, - const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'}, + const {'1': 'block_orders', '3': 3, '4': 3, '5': 11, '6': '.GridBlockOrder', '10': 'blockOrders'}, ], }; /// Descriptor for `Grid`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxImCgZibG9ja3MYAyADKAsyDi5HcmlkQmxvY2tNZXRhUgZibG9ja3M='); +final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxIyCgxibG9ja19vcmRlcnMYAyADKAsyDy5HcmlkQmxvY2tPcmRlclILYmxvY2tPcmRlcnM='); @$core.Deprecated('Use fieldDescriptor instead') const Field$json = const { '1': 'Field', @@ -110,6 +110,16 @@ const Row_CellByFieldIdEntry$json = const { /// Descriptor for `Row`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List rowDescriptor = $convert.base64Decode('CgNSb3cSDgoCaWQYASABKAlSAmlkEkAKEGNlbGxfYnlfZmllbGRfaWQYAiADKAsyFy5Sb3cuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgDIAEoBVIGaGVpZ2h0GkcKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIbCgV2YWx1ZRgCIAEoCzIFLkNlbGxSBXZhbHVlOgI4AQ=='); +@$core.Deprecated('Use repeatedRowDescriptor instead') +const RepeatedRow$json = const { + '1': 'RepeatedRow', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Row', '10': 'items'}, + ], +}; + +/// Descriptor for `RepeatedRow`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedRowDescriptor = $convert.base64Decode('CgtSZXBlYXRlZFJvdxIaCgVpdGVtcxgBIAMoCzIELlJvd1IFaXRlbXM='); @$core.Deprecated('Use repeatedGridBlockDescriptor instead') const RepeatedGridBlock$json = const { '1': 'RepeatedGridBlock', @@ -120,17 +130,27 @@ const RepeatedGridBlock$json = const { /// Descriptor for `RepeatedGridBlock`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List repeatedGridBlockDescriptor = $convert.base64Decode('ChFSZXBlYXRlZEdyaWRCbG9jaxIgCgVpdGVtcxgBIAMoCzIKLkdyaWRCbG9ja1IFaXRlbXM='); +@$core.Deprecated('Use gridBlockOrderDescriptor instead') +const GridBlockOrder$json = const { + '1': 'GridBlockOrder', + '2': const [ + const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, + ], +}; + +/// Descriptor for `GridBlockOrder`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockOrderDescriptor = $convert.base64Decode('Cg5HcmlkQmxvY2tPcmRlchIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZA=='); @$core.Deprecated('Use gridBlockDescriptor instead') const GridBlock$json = const { '1': 'GridBlock', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.Row', '10': 'rows'}, + const {'1': 'row_ids', '3': 2, '4': 3, '5': 9, '10': 'rowIds'}, ], }; /// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSGAoEcm93cxgCIAMoCzIELlJvd1IEcm93cw=='); +final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSFwoHcm93X2lkcxgCIAMoCVIGcm93SWRz'); @$core.Deprecated('Use cellDescriptor instead') const Cell$json = const { '1': 'Cell', @@ -187,15 +207,15 @@ const CreateRowPayload$json = const { '1': 'CreateRowPayload', '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'upper_row_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'upperRowId'}, + const {'1': 'start_row_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'startRowId'}, ], '8': const [ - const {'1': 'one_of_upper_row_id'}, + const {'1': 'one_of_start_row_id'}, ], }; /// Descriptor for `CreateRowPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createRowPayloadDescriptor = $convert.base64Decode('ChBDcmVhdGVSb3dQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIiCgx1cHBlcl9yb3dfaWQYAiABKAlIAFIKdXBwZXJSb3dJZEIVChNvbmVfb2ZfdXBwZXJfcm93X2lk'); +final $typed_data.Uint8List createRowPayloadDescriptor = $convert.base64Decode('ChBDcmVhdGVSb3dQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIiCgxzdGFydF9yb3dfaWQYAiABKAlIAFIKc3RhcnRSb3dJZEIVChNvbmVfb2Zfc3RhcnRfcm93X2lk'); @$core.Deprecated('Use queryFieldPayloadDescriptor instead') const QueryFieldPayload$json = const { '1': 'QueryFieldPayload', @@ -212,9 +232,21 @@ const QueryGridBlocksPayload$json = const { '1': 'QueryGridBlocksPayload', '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'blocks', '3': 2, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'}, + const {'1': 'block_orders', '3': 2, '4': 3, '5': 11, '6': '.GridBlockOrder', '10': 'blockOrders'}, ], }; /// Descriptor for `QueryGridBlocksPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List queryGridBlocksPayloadDescriptor = $convert.base64Decode('ChZRdWVyeUdyaWRCbG9ja3NQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBImCgZibG9ja3MYAiADKAsyDi5HcmlkQmxvY2tNZXRhUgZibG9ja3M='); +final $typed_data.Uint8List queryGridBlocksPayloadDescriptor = $convert.base64Decode('ChZRdWVyeUdyaWRCbG9ja3NQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIyCgxibG9ja19vcmRlcnMYAiADKAsyDy5HcmlkQmxvY2tPcmRlclILYmxvY2tPcmRlcnM='); +@$core.Deprecated('Use queryRowPayloadDescriptor instead') +const QueryRowPayload$json = const { + '1': 'QueryRowPayload', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'block_id', '3': 2, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'row_id', '3': 3, '4': 1, '5': 9, '10': 'rowId'}, + ], +}; + +/// Descriptor for `QueryRowPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List queryRowPayloadDescriptor = $convert.base64Decode('Cg9RdWVyeVJvd1BheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhkKCGJsb2NrX2lkGAIgASgJUgdibG9ja0lkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart index 0a3cba6be6..4bbeae52a5 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart @@ -17,7 +17,7 @@ class GridMeta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) - ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: GridBlockMeta.create) + ..pc(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetas', $pb.PbFieldType.PM, subBuilder: GridBlockMeta.create) ..hasRequiredFields = false ; @@ -25,7 +25,7 @@ class GridMeta extends $pb.GeneratedMessage { factory GridMeta({ $core.String? gridId, $core.Iterable? fields, - $core.Iterable? blocks, + $core.Iterable? blockMetas, }) { final _result = create(); if (gridId != null) { @@ -34,8 +34,8 @@ class GridMeta extends $pb.GeneratedMessage { if (fields != null) { _result.fields.addAll(fields); } - if (blocks != null) { - _result.blocks.addAll(blocks); + if (blockMetas != null) { + _result.blockMetas.addAll(blockMetas); } return _result; } @@ -73,7 +73,7 @@ class GridMeta extends $pb.GeneratedMessage { $core.List get fields => $_getList(1); @$pb.TagNumber(3) - $core.List get blocks => $_getList(2); + $core.List get blockMetas => $_getList(2); } class GridBlockMeta extends $pb.GeneratedMessage { @@ -151,15 +151,15 @@ class GridBlockMeta extends $pb.GeneratedMessage { void clearRowCount() => clearField(3); } -class GridBlockMetaData extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMetaData', createEmptyInstance: create) +class GridBlockMetaSerde extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMetaSerde', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowMetas', $pb.PbFieldType.PM, subBuilder: RowMeta.create) ..hasRequiredFields = false ; - GridBlockMetaData._() : super(); - factory GridBlockMetaData({ + GridBlockMetaSerde._() : super(); + factory GridBlockMetaSerde({ $core.String? blockId, $core.Iterable? rowMetas, }) { @@ -172,26 +172,26 @@ class GridBlockMetaData extends $pb.GeneratedMessage { } return _result; } - factory GridBlockMetaData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GridBlockMetaData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory GridBlockMetaSerde.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridBlockMetaSerde.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Will be removed in next major version') - GridBlockMetaData clone() => GridBlockMetaData()..mergeFromMessage(this); + GridBlockMetaSerde clone() => GridBlockMetaSerde()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - GridBlockMetaData copyWith(void Function(GridBlockMetaData) updates) => super.copyWith((message) => updates(message as GridBlockMetaData)) as GridBlockMetaData; // ignore: deprecated_member_use + GridBlockMetaSerde copyWith(void Function(GridBlockMetaSerde) updates) => super.copyWith((message) => updates(message as GridBlockMetaSerde)) as GridBlockMetaSerde; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static GridBlockMetaData create() => GridBlockMetaData._(); - GridBlockMetaData createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static GridBlockMetaSerde create() => GridBlockMetaSerde._(); + GridBlockMetaSerde createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static GridBlockMetaData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GridBlockMetaData? _defaultInstance; + static GridBlockMetaSerde getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridBlockMetaSerde? _defaultInstance; @$pb.TagNumber(1) $core.String get blockId => $_getSZ(0); @@ -1020,26 +1020,26 @@ class CellMetaChangeset extends $pb.GeneratedMessage { class BuildGridContext extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BuildGridContext', createEmptyInstance: create) ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldMetas', $pb.PbFieldType.PM, subBuilder: FieldMeta.create) - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlock', subBuilder: GridBlockMeta.create) - ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlockMetaData', subBuilder: GridBlockMetaData.create) + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetas', subBuilder: GridBlockMeta.create) + ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetaData', subBuilder: GridBlockMetaSerde.create) ..hasRequiredFields = false ; BuildGridContext._() : super(); factory BuildGridContext({ $core.Iterable? fieldMetas, - GridBlockMeta? gridBlock, - GridBlockMetaData? gridBlockMetaData, + GridBlockMeta? blockMetas, + GridBlockMetaSerde? blockMetaData, }) { final _result = create(); if (fieldMetas != null) { _result.fieldMetas.addAll(fieldMetas); } - if (gridBlock != null) { - _result.gridBlock = gridBlock; + if (blockMetas != null) { + _result.blockMetas = blockMetas; } - if (gridBlockMetaData != null) { - _result.gridBlockMetaData = gridBlockMetaData; + if (blockMetaData != null) { + _result.blockMetaData = blockMetaData; } return _result; } @@ -1068,25 +1068,25 @@ class BuildGridContext extends $pb.GeneratedMessage { $core.List get fieldMetas => $_getList(0); @$pb.TagNumber(2) - GridBlockMeta get gridBlock => $_getN(1); + GridBlockMeta get blockMetas => $_getN(1); @$pb.TagNumber(2) - set gridBlock(GridBlockMeta v) { setField(2, v); } + set blockMetas(GridBlockMeta v) { setField(2, v); } @$pb.TagNumber(2) - $core.bool hasGridBlock() => $_has(1); + $core.bool hasBlockMetas() => $_has(1); @$pb.TagNumber(2) - void clearGridBlock() => clearField(2); + void clearBlockMetas() => clearField(2); @$pb.TagNumber(2) - GridBlockMeta ensureGridBlock() => $_ensure(1); + GridBlockMeta ensureBlockMetas() => $_ensure(1); @$pb.TagNumber(3) - GridBlockMetaData get gridBlockMetaData => $_getN(2); + GridBlockMetaSerde get blockMetaData => $_getN(2); @$pb.TagNumber(3) - set gridBlockMetaData(GridBlockMetaData v) { setField(3, v); } + set blockMetaData(GridBlockMetaSerde v) { setField(3, v); } @$pb.TagNumber(3) - $core.bool hasGridBlockMetaData() => $_has(2); + $core.bool hasBlockMetaData() => $_has(2); @$pb.TagNumber(3) - void clearGridBlockMetaData() => clearField(3); + void clearBlockMetaData() => clearField(3); @$pb.TagNumber(3) - GridBlockMetaData ensureGridBlockMetaData() => $_ensure(2); + GridBlockMetaSerde ensureBlockMetaData() => $_ensure(2); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart index 7048fb3c81..d20b9da3f5 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart @@ -29,12 +29,12 @@ const GridMeta$json = const { '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fields'}, - const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'}, + const {'1': 'block_metas', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blockMetas'}, ], }; /// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSJgoGYmxvY2tzGAMgAygLMg4uR3JpZEJsb2NrTWV0YVIGYmxvY2tz'); +final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSLwoLYmxvY2tfbWV0YXMYAyADKAsyDi5HcmlkQmxvY2tNZXRhUgpibG9ja01ldGFz'); @$core.Deprecated('Use gridBlockMetaDescriptor instead') const GridBlockMeta$json = const { '1': 'GridBlockMeta', @@ -47,17 +47,17 @@ const GridBlockMeta$json = const { /// Descriptor for `GridBlockMeta`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridBlockMetaDescriptor = $convert.base64Decode('Cg1HcmlkQmxvY2tNZXRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEiYKD3N0YXJ0X3Jvd19pbmRleBgCIAEoBVINc3RhcnRSb3dJbmRleBIbCglyb3dfY291bnQYAyABKAVSCHJvd0NvdW50'); -@$core.Deprecated('Use gridBlockMetaDataDescriptor instead') -const GridBlockMetaData$json = const { - '1': 'GridBlockMetaData', +@$core.Deprecated('Use gridBlockMetaSerdeDescriptor instead') +const GridBlockMetaSerde$json = const { + '1': 'GridBlockMetaSerde', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, const {'1': 'row_metas', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rowMetas'}, ], }; -/// Descriptor for `GridBlockMetaData`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockMetaDataDescriptor = $convert.base64Decode('ChFHcmlkQmxvY2tNZXRhRGF0YRIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIlCglyb3dfbWV0YXMYAiADKAsyCC5Sb3dNZXRhUghyb3dNZXRhcw=='); +/// Descriptor for `GridBlockMetaSerde`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridBlockMetaSerdeDescriptor = $convert.base64Decode('ChJHcmlkQmxvY2tNZXRhU2VyZGUSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSJQoJcm93X21ldGFzGAIgAygLMgguUm93TWV0YVIIcm93TWV0YXM='); @$core.Deprecated('Use fieldMetaDescriptor instead') const FieldMeta$json = const { '1': 'FieldMeta', @@ -197,10 +197,10 @@ const BuildGridContext$json = const { '1': 'BuildGridContext', '2': const [ const {'1': 'field_metas', '3': 1, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fieldMetas'}, - const {'1': 'grid_block', '3': 2, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'gridBlock'}, - const {'1': 'grid_block_meta_data', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMetaData', '10': 'gridBlockMetaData'}, + const {'1': 'block_metas', '3': 2, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'blockMetas'}, + const {'1': 'block_meta_data', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMetaSerde', '10': 'blockMetaData'}, ], }; /// Descriptor for `BuildGridContext`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEi0KCmdyaWRfYmxvY2sYAiABKAsyDi5HcmlkQmxvY2tNZXRhUglncmlkQmxvY2sSQwoUZ3JpZF9ibG9ja19tZXRhX2RhdGEYAyABKAsyEi5HcmlkQmxvY2tNZXRhRGF0YVIRZ3JpZEJsb2NrTWV0YURhdGE='); +final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEi8KC2Jsb2NrX21ldGFzGAIgASgLMg4uR3JpZEJsb2NrTWV0YVIKYmxvY2tNZXRhcxI7Cg9ibG9ja19tZXRhX2RhdGEYAyABKAsyEy5HcmlkQmxvY2tNZXRhU2VyZGVSDWJsb2NrTWV0YURhdGE='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart index 54f33ea020..f68b10f292 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbenum.dart @@ -12,12 +12,14 @@ import 'package:protobuf/protobuf.dart' as $pb; class GridNotification extends $pb.ProtobufEnum { static const GridNotification Unknown = GridNotification._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown'); static const GridNotification GridDidUpdateBlock = GridNotification._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateBlock'); + static const GridNotification GridDidCreateBlock = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidCreateBlock'); static const GridNotification GridDidUpdateCells = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateCells'); static const GridNotification GridDidUpdateFields = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateFields'); static const $core.List values = [ Unknown, GridDidUpdateBlock, + GridDidCreateBlock, GridDidUpdateCells, GridDidUpdateFields, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart index 4c4ff69eb1..b266e63e09 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/dart_notification.pbjson.dart @@ -14,10 +14,11 @@ const GridNotification$json = const { '2': const [ const {'1': 'Unknown', '2': 0}, const {'1': 'GridDidUpdateBlock', '2': 10}, + const {'1': 'GridDidCreateBlock', '2': 11}, const {'1': 'GridDidUpdateCells', '2': 20}, const {'1': 'GridDidUpdateFields', '2': 30}, ], }; /// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIWChJHcmlkRGlkVXBkYXRlQmxvY2sQChIWChJHcmlkRGlkVXBkYXRlQ2VsbHMQFBIXChNHcmlkRGlkVXBkYXRlRmllbGRzEB4='); +final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIWChJHcmlkRGlkVXBkYXRlQmxvY2sQChIWChJHcmlkRGlkQ3JlYXRlQmxvY2sQCxIWChJHcmlkRGlkVXBkYXRlQ2VsbHMQFBIXChNHcmlkRGlkVXBkYXRlRmllbGRzEB4='); 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 787f44e52c..91a3861076 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 @@ -12,15 +12,17 @@ import 'package:protobuf/protobuf.dart' as $pb; class GridEvent extends $pb.ProtobufEnum { static const GridEvent GetGridData = GridEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetGridData'); static const GridEvent GetGridBlocks = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetGridBlocks'); - static const GridEvent GetFields = GridEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields'); - static const GridEvent CreateRow = GridEvent._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); - static const GridEvent UpdateCell = GridEvent._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); + static const GridEvent GetFields = GridEvent._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields'); + static const GridEvent CreateRow = GridEvent._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); + static const GridEvent GetRow = GridEvent._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); + static const GridEvent UpdateCell = GridEvent._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); static const $core.List values = [ GetGridData, GetGridBlocks, GetFields, CreateRow, + GetRow, UpdateCell, ]; 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 707eca7c61..c203b10c75 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 @@ -14,11 +14,12 @@ const GridEvent$json = const { '2': const [ const {'1': 'GetGridData', '2': 0}, const {'1': 'GetGridBlocks', '2': 1}, - const {'1': 'GetFields', '2': 2}, - const {'1': 'CreateRow', '2': 3}, - const {'1': 'UpdateCell', '2': 4}, + const {'1': 'GetFields', '2': 10}, + const {'1': 'CreateRow', '2': 11}, + const {'1': 'GetRow', '2': 12}, + const {'1': 'UpdateCell', '2': 20}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAMSDgoKVXBkYXRlQ2VsbBAE'); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDQoJQ3JlYXRlUm93EAsSCgoGR2V0Um93EAwSDgoKVXBkYXRlQ2VsbBAU'); diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 30aa28a798..929fcad90c 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1088,6 +1088,7 @@ version = "0.1.0" dependencies = [ "bytes", "flowy-derive", + "flowy-error-code", "lib-infra", "protobuf", "serde", diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 96755db623..046fd85668 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [lib] name = "dart_ffi" # this value will change depending on the target os -# default staticlib -crate-type = ["staticlib"] +# default cdylib +crate-type = ["cdylib"] [dependencies] diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 8921d15aea..d6022769fb 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,9 +1,10 @@ use crate::manager::GridManager; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ - CellMetaChangeset, CreateRowPayload, Field, Grid, GridId, QueryFieldPayload, QueryGridBlocksPayload, RepeatedField, - RepeatedGridBlock, Row, + CellMetaChangeset, CreateRowPayload, Field, Grid, GridId, QueryFieldPayload, QueryGridBlocksPayload, + QueryRowPayload, RepeatedField, RepeatedGridBlock, RepeatedRow, Row, }; +use flowy_grid_data_model::parser::{CreateRowParams, QueryFieldParams, QueryGridBlocksParams, QueryRowParams}; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -23,20 +24,38 @@ pub(crate) async fn get_grid_blocks_handler( data: Data, manager: AppData>, ) -> DataResult { - let payload: QueryGridBlocksPayload = data.into_inner(); - let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_grid_block = editor.get_grid_blocks(Some(payload.blocks)).await?; + let params: QueryGridBlocksParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + let block_ids = params + .block_orders + .into_iter() + .map(|block| block.block_id) + .collect::>(); + let repeated_grid_block = editor.get_blocks(Some(block_ids)).await?; data_result(repeated_grid_block) } +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn get_row_handler( + data: Data, + manager: AppData>, +) -> DataResult { + let params: QueryRowParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + match editor.get_row(¶ms.block_id, ¶ms.row_id).await? { + None => Err(FlowyError::record_not_found().context("Can not find the row")), + Some(row) => data_result(row), + } +} + #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn get_fields_handler( data: Data, manager: AppData>, ) -> DataResult { - let payload: QueryFieldPayload = data.into_inner(); - let editor = manager.get_grid_editor(&payload.grid_id)?; - let field_metas = editor.get_field_metas(Some(payload.field_orders)).await?; + let params: QueryFieldParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + let field_metas = editor.get_field_metas(Some(params.field_orders)).await?; let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::>().into(); data_result(repeated_field) } @@ -46,9 +65,9 @@ pub(crate) async fn create_row_handler( data: Data, manager: AppData>, ) -> Result<(), FlowyError> { - let payload: CreateRowPayload = data.into_inner(); - let editor = manager.get_grid_editor(payload.grid_id.as_ref())?; - let _ = editor.create_row(payload.upper_row_id).await?; + let params: CreateRowParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(params.grid_id.as_ref())?; + let _ = editor.create_row(params.start_row_id).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index d748b3b882..03b27f4c70 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -12,6 +12,7 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::GetGridBlocks, get_grid_blocks_handler) .event(GridEvent::GetFields, get_fields_handler) .event(GridEvent::CreateRow, create_row_handler) + .event(GridEvent::GetRow, get_row_handler) .event(GridEvent::UpdateCell, update_cell_handler); module @@ -27,11 +28,14 @@ pub enum GridEvent { GetGridBlocks = 1, #[event(input = "QueryFieldPayload", output = "RepeatedField")] - GetFields = 2, + GetFields = 10, #[event(input = "CreateRowPayload", output = "Row")] - CreateRow = 3, + CreateRow = 11, + + #[event(input = "QueryRowPayload", output = "Row")] + GetRow = 12, #[event(input = "CellMetaChangeset")] - UpdateCell = 4, + UpdateCell = 20, } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 7afcdf05fd..104f74d5f4 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -182,11 +182,11 @@ pub async fn make_grid_view_data( grid_manager: Arc, build_context: BuildGridContext, ) -> FlowyResult { - let block_id = build_context.grid_block.block_id.clone(); + let block_id = build_context.block_metas.block_id.clone(); let grid_meta = GridMeta { grid_id: view_id.to_string(), fields: build_context.field_metas, - blocks: vec![build_context.grid_block], + block_metas: vec![build_context.block_metas], }; let grid_meta_delta = make_grid_delta(&grid_meta); @@ -195,7 +195,7 @@ pub async fn make_grid_view_data( Revision::initial_revision(user_id, view_id, grid_delta_data.clone()).into(); let _ = grid_manager.create_grid(view_id, repeated_revision).await?; - let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta_data); + let grid_block_meta_delta = make_block_meta_delta(&build_context.block_meta_data); let block_meta_delta_data = grid_block_meta_delta.to_delta_bytes(); let repeated_revision: RepeatedRevision = Revision::initial_revision(user_id, &block_id, block_meta_delta_data).into(); diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs index a4f7fbb46c..72b3f12abd 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/dart_notification.rs @@ -27,6 +27,7 @@ pub enum GridNotification { Unknown = 0, GridDidUpdateBlock = 10, + GridDidCreateBlock = 11, GridDidUpdateCells = 20, GridDidUpdateFields = 30, } @@ -40,6 +41,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { match value { 0 => ::std::option::Option::Some(GridNotification::Unknown), 10 => ::std::option::Option::Some(GridNotification::GridDidUpdateBlock), + 11 => ::std::option::Option::Some(GridNotification::GridDidCreateBlock), 20 => ::std::option::Option::Some(GridNotification::GridDidUpdateCells), 30 => ::std::option::Option::Some(GridNotification::GridDidUpdateFields), _ => ::std::option::Option::None @@ -50,6 +52,7 @@ impl ::protobuf::ProtobufEnum for GridNotification { static values: &'static [GridNotification] = &[ GridNotification::Unknown, GridNotification::GridDidUpdateBlock, + GridNotification::GridDidCreateBlock, GridNotification::GridDidUpdateCells, GridNotification::GridDidUpdateFields, ]; @@ -80,9 +83,10 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x17dart_notification.proto*h\n\x10GridNotification\x12\x0b\n\x07Unkno\ - wn\x10\0\x12\x16\n\x12GridDidUpdateBlock\x10\n\x12\x16\n\x12GridDidUpdat\ - eCells\x10\x14\x12\x17\n\x13GridDidUpdateFields\x10\x1eb\x06proto3\ + \n\x17dart_notification.proto*\x80\x01\n\x10GridNotification\x12\x0b\n\ + \x07Unknown\x10\0\x12\x16\n\x12GridDidUpdateBlock\x10\n\x12\x16\n\x12Gri\ + dDidCreateBlock\x10\x0b\x12\x16\n\x12GridDidUpdateCells\x10\x14\x12\x17\ + \n\x13GridDidUpdateFields\x10\x1eb\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/model/event_map.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs index 1ed38366d4..9feb87fec5 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 @@ -27,9 +27,10 @@ pub enum GridEvent { GetGridData = 0, GetGridBlocks = 1, - GetFields = 2, - CreateRow = 3, - UpdateCell = 4, + GetFields = 10, + CreateRow = 11, + GetRow = 12, + UpdateCell = 20, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -41,9 +42,10 @@ impl ::protobuf::ProtobufEnum for GridEvent { match value { 0 => ::std::option::Option::Some(GridEvent::GetGridData), 1 => ::std::option::Option::Some(GridEvent::GetGridBlocks), - 2 => ::std::option::Option::Some(GridEvent::GetFields), - 3 => ::std::option::Option::Some(GridEvent::CreateRow), - 4 => ::std::option::Option::Some(GridEvent::UpdateCell), + 10 => ::std::option::Option::Some(GridEvent::GetFields), + 11 => ::std::option::Option::Some(GridEvent::CreateRow), + 12 => ::std::option::Option::Some(GridEvent::GetRow), + 20 => ::std::option::Option::Some(GridEvent::UpdateCell), _ => ::std::option::Option::None } } @@ -54,6 +56,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::GetGridBlocks, GridEvent::GetFields, GridEvent::CreateRow, + GridEvent::GetRow, GridEvent::UpdateCell, ]; values @@ -83,9 +86,10 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*]\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\ - \x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\x02\x12\r\n\tCreate\ - Row\x10\x03\x12\x0e\n\nUpdateCell\x10\x04b\x06proto3\ + \n\x0fevent_map.proto*i\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\ + \x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\r\n\tCreateRo\ + w\x10\x0b\x12\n\n\x06GetRow\x10\x0c\x12\x0e\n\nUpdateCell\x10\x14b\x06pr\ + oto3\ "; 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/dart_notification.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto index 9aadc14372..0262b34477 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/dart_notification.proto @@ -3,6 +3,7 @@ syntax = "proto3"; enum GridNotification { Unknown = 0; GridDidUpdateBlock = 10; + GridDidCreateBlock = 11; GridDidUpdateCells = 20; GridDidUpdateFields = 30; } 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 a5c998e7e1..6c39e618f5 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 @@ -3,7 +3,8 @@ syntax = "proto3"; enum GridEvent { GetGridData = 0; GetGridBlocks = 1; - GetFields = 2; - CreateRow = 3; - UpdateCell = 4; + GetFields = 10; + CreateRow = 11; + GetRow = 12; + UpdateCell = 20; } 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 21046c295c..f8ba93b906 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 @@ -1,14 +1,15 @@ use crate::manager::GridUser; -use crate::services::row::{make_cell, make_grid_blocks, make_row_ids_per_block, GridBlockMetaDataSnapshot}; +use crate::services::row::{make_cell, make_row_ids_per_block, GridBlockMetaData}; use bytes::Bytes; +use crate::dart_notification::{send_dart_notification, GridNotification}; use dashmap::DashMap; -use flowy_collaboration::client_grid::{GridBlockMetaDataChange, GridBlockMetaDataPad}; +use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Cell, FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, RepeatedCell, RepeatedRowOrder, RowMeta, + FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, RepeatedCell, RepeatedRowOrder, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; @@ -17,10 +18,7 @@ use flowy_sync::{ }; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; - use std::collections::HashMap; - -use crate::dart_notification::{send_dart_notification, GridNotification}; use std::sync::Arc; use tokio::sync::RwLock; @@ -30,7 +28,7 @@ type BlockId = String; pub(crate) struct GridBlockMetaEditorManager { grid_id: String, user: Arc, - editor_map: DashMap>, + editor_map: DashMap>, block_id_by_row_id: DashMap, } @@ -49,7 +47,7 @@ impl GridBlockMetaEditorManager { Ok(manager) } - pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult> { + pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult> { match self.editor_map.get(block_id) { None => { tracing::error!("The is a fatal error, block is not exist"); @@ -124,6 +122,16 @@ impl GridBlockMetaEditorManager { Ok(()) } + pub async fn get_row(&self, block_id: &str, row_id: &str) -> FlowyResult>> { + let editor = self.get_editor(block_id).await?; + let mut row_metas = editor.get_row_metas(Some(vec![row_id.to_owned()])).await?; + if row_metas.is_empty() { + Ok(None) + } else { + Ok(row_metas.pop()) + } + } + pub async fn update_cells(&self, field_metas: &[FieldMeta], changeset: RowMetaChangeset) -> FlowyResult<()> { let editor = self.get_editor_from_row_id(&changeset.row_id).await?; let _ = editor.update_row(changeset.clone()).await?; @@ -131,10 +139,10 @@ impl GridBlockMetaEditorManager { Ok(()) } - pub(crate) async fn get_block_meta_snapshot_from_blocks( + pub(crate) async fn get_block_meta_data_from_blocks( &self, grid_blocks: Vec, - ) -> FlowyResult> { + ) -> FlowyResult> { let mut snapshots = vec![]; for grid_block in grid_blocks { let editor = self.get_editor(&grid_block.block_id).await?; @@ -144,7 +152,7 @@ impl GridBlockMetaEditorManager { .insert(row_meta.id.clone(), row_meta.block_id.clone()); }); - snapshots.push(GridBlockMetaDataSnapshot { + snapshots.push(GridBlockMetaData { block_id: grid_block.block_id, row_metas, }); @@ -152,20 +160,17 @@ impl GridBlockMetaEditorManager { Ok(snapshots) } - pub(crate) async fn get_block_meta_snapshot_from_row_orders( - &self, - grid_block_metas: &Vec, - ) -> FlowyResult> { + pub(crate) async fn get_block_meta_data(&self, block_ids: &[String]) -> FlowyResult> { let mut snapshots = vec![]; - for grid_block_meta in grid_block_metas { - let editor = self.get_editor(&grid_block_meta.block_id).await?; + for block_id in block_ids { + let editor = self.get_editor(&block_id).await?; let row_metas = editor.get_row_metas(None).await?; row_metas.iter().for_each(|row_meta| { self.block_id_by_row_id .insert(row_meta.id.clone(), row_meta.block_id.clone()); }); - snapshots.push(GridBlockMetaDataSnapshot { - block_id: grid_block_meta.block_id.clone(), + snapshots.push(GridBlockMetaData { + block_id: block_id.clone(), row_metas, }); } @@ -182,7 +187,7 @@ impl GridBlockMetaEditorManager { Ok(row_orders) } - async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { + async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { match self.block_id_by_row_id.get(row_id) { None => { let msg = format!( @@ -237,7 +242,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?; @@ -247,10 +252,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()?; @@ -258,17 +260,17 @@ async fn make_block_meta_editor( 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); - ClientGridBlockMetaDataEditor::new(&user_id, &token, block_id, rev_manager).await + ClientGridBlockMetaEditor::new(&user_id, &token, block_id, rev_manager).await } -pub struct ClientGridBlockMetaDataEditor { +pub struct ClientGridBlockMetaEditor { user_id: String, pub block_id: String, - pad: Arc>, + pad: Arc>, rev_manager: Arc, } -impl ClientGridBlockMetaDataEditor { +impl ClientGridBlockMetaEditor { pub async fn new( user_id: &str, token: &str, @@ -340,7 +342,7 @@ impl ClientGridBlockMetaDataEditor { async fn modify(&self, f: F) -> FlowyResult<()> where - F: for<'a> FnOnce(&'a mut GridBlockMetaDataPad) -> FlowyResult>, + F: for<'a> FnOnce(&'a mut GridBlockMetaPad) -> FlowyResult>, { let mut write_guard = self.pad.write().await; match f(&mut *write_guard)? { @@ -352,8 +354,8 @@ impl ClientGridBlockMetaDataEditor { Ok(()) } - async fn apply_change(&self, change: GridBlockMetaDataChange) -> FlowyResult<()> { - let GridBlockMetaDataChange { delta, md5 } = change; + async fn apply_change(&self, change: GridBlockMetaChange) -> FlowyResult<()> { + let GridBlockMetaChange { delta, md5 } = change; let user_id = self.user_id.clone(); let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair(); let delta_data = delta.to_delta_bytes(); @@ -387,10 +389,10 @@ impl RevisionCloudService for GridBlockMetaRevisionCloudService { struct GridBlockMetaPadBuilder(); impl RevisionObjectBuilder for GridBlockMetaPadBuilder { - type Output = GridBlockMetaDataPad; + type Output = GridBlockMetaPad; fn build_object(object_id: &str, revisions: Vec) -> FlowyResult { - let pad = GridBlockMetaDataPad::from_revisions(object_id, revisions)?; + let pad = GridBlockMetaPad::from_revisions(object_id, revisions)?; Ok(pad) } } 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 f991d26a10..8f4d82d992 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -7,14 +7,15 @@ use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ Cell, CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlockMeta, GridBlockMetaChangeset, - RepeatedField, RepeatedFieldOrder, RepeatedGridBlock, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, + GridBlockOrder, RepeatedField, RepeatedFieldOrder, RepeatedGridBlock, RepeatedRow, RepeatedRowOrder, Row, RowMeta, + RowMetaChangeset, }; use std::collections::HashMap; use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::services::row::{ - make_grid_block_from_block_metas, make_grid_blocks, make_row_ids_per_block, row_meta_from_context, - serialize_cell_data, GridBlockMetaDataSnapshot, RowMetaContext, RowMetaContextBuilder, + make_grid_block_from_block_metas, make_grid_blocks, make_row_ids_per_block, make_rows_from_row_metas, + row_meta_from_context, serialize_cell_data, GridBlockMetaData, RowMetaContext, RowMetaContextBuilder, }; use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; @@ -125,6 +126,33 @@ impl ClientGridEditor { self.block_meta_manager.update_row(changeset).await } + pub async fn get_rows(&self, block_id: &str) -> FlowyResult { + let block_ids = vec![block_id.to_owned()]; + let mut block_meta_data_vec = self.get_block_meta_data_vec(Some(&block_ids)).await?; + debug_assert_eq!(block_meta_data_vec.len(), 1); + if block_meta_data_vec.len() == 1 { + let block_meta_data = block_meta_data_vec.pop().unwrap(); + let field_metas = self.get_field_metas(None).await?; + let rows = make_rows_from_row_metas(&field_metas, &block_meta_data.row_metas); + Ok(rows.into()) + } else { + Ok(vec![].into()) + } + } + + pub async fn get_row(&self, block_id: &str, row_id: &str) -> FlowyResult> { + match self.block_meta_manager.get_row(block_id, row_id).await? { + None => Ok(None), + Some(row) => { + let field_metas = self.get_field_metas(None).await?; + let row_metas = vec![row]; + let mut rows = make_rows_from_row_metas(&field_metas, &row_metas); + debug_assert!(rows.len() == 1); + Ok(rows.pop()) + } + } + } + pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> { if let Some(cell_data) = changeset.data.as_ref() { match self.pad.read().await.get_field(&changeset.field_id) { @@ -147,41 +175,17 @@ impl ClientGridEditor { Ok(()) } - pub async fn get_grid_blocks( - &self, - grid_block_metas: Option>, - ) -> FlowyResult { - let grid_block_meta_snapshots = self.get_grid_block_meta_snapshots(grid_block_metas.as_ref()).await?; - let field_meta = self.pad.read().await.get_field_metas(None)?; - match grid_block_metas { - None => make_grid_blocks(&field_meta, grid_block_meta_snapshots), - Some(grid_block_metas) => { - make_grid_block_from_block_metas(&field_meta, grid_block_metas, grid_block_meta_snapshots) - } + pub async fn get_blocks(&self, block_ids: Option>) -> FlowyResult { + let block_meta_data_vec = self.get_block_meta_data_vec(block_ids.as_ref()).await?; + match block_ids { + None => make_grid_blocks(block_meta_data_vec), + Some(block_ids) => make_grid_block_from_block_metas(&block_ids, block_meta_data_vec), } } - pub(crate) async fn get_grid_block_meta_snapshots( - &self, - grid_block_infos: Option<&Vec>, - ) -> FlowyResult> { - match grid_block_infos { - None => { - let grid_blocks = self.pad.read().await.get_blocks(); - let row_metas_per_block = self - .block_meta_manager - .get_block_meta_snapshot_from_blocks(grid_blocks) - .await?; - Ok(row_metas_per_block) - } - Some(grid_block_infos) => { - let row_metas_per_block = self - .block_meta_manager - .get_block_meta_snapshot_from_row_orders(grid_block_infos) - .await?; - Ok(row_metas_per_block) - } - } + pub async fn get_block_metas(&self) -> FlowyResult> { + let grid_blocks = self.pad.read().await.get_blocks(); + Ok(grid_blocks) } pub async fn delete_rows(&self, row_ids: Vec) -> FlowyResult<()> { @@ -194,11 +198,20 @@ impl ClientGridEditor { pub async fn grid_data(&self) -> FlowyResult { let field_orders = self.pad.read().await.get_field_orders(); - let block_orders = self.pad.read().await.get_blocks(); + let block_orders = self + .pad + .read() + .await + .get_blocks() + .into_iter() + .map(|grid_block_meta| GridBlockOrder { + block_id: grid_block_meta.block_id, + }) + .collect::>(); Ok(Grid { id: self.grid_id.clone(), field_orders, - blocks: block_orders, + block_orders, }) } @@ -207,9 +220,27 @@ impl ClientGridEditor { Ok(field_meta) } - pub async fn get_blocks(&self) -> FlowyResult> { - let grid_blocks = self.pad.read().await.get_blocks(); - Ok(grid_blocks) + pub async fn get_block_meta_data_vec( + &self, + block_ids: Option<&Vec>, + ) -> FlowyResult> { + match block_ids { + None => { + let grid_blocks = self.pad.read().await.get_blocks(); + let row_metas_per_block = self + .block_meta_manager + .get_block_meta_data_from_blocks(grid_blocks) + .await?; + Ok(row_metas_per_block) + } + Some(block_ids) => { + let row_metas_per_block = self + .block_meta_manager + .get_block_meta_data(block_ids.as_slice()) + .await?; + Ok(row_metas_per_block) + } + } } pub async fn delta_bytes(&self) -> Bytes { 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 953a950917..8d1e683a6e 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 @@ -1,11 +1,11 @@ use crate::services::row::deserialize_cell_data; use flowy_error::FlowyResult; use flowy_grid_data_model::entities::{ - Cell, CellMeta, FieldMeta, GridBlock, GridBlockMeta, RepeatedGridBlock, RepeatedRowOrder, Row, RowMeta, RowOrder, + Cell, CellMeta, FieldMeta, GridBlock, RepeatedGridBlock, RepeatedRowOrder, Row, RowMeta, RowOrder, }; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; -use std::ops::Deref; + use std::sync::Arc; pub(crate) struct RowIdsPerBlock { @@ -22,9 +22,9 @@ impl RowIdsPerBlock { } } -pub(crate) struct GridBlockMetaDataSnapshot { +pub struct GridBlockMetaData { pub(crate) block_id: String, - pub(crate) row_metas: Vec>, + pub row_metas: Vec>, } pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec { @@ -40,17 +40,14 @@ pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec>() } -pub(crate) fn make_grid_blocks( - field_metas: &[FieldMeta], - grid_block_meta_snapshots: Vec, -) -> FlowyResult { - Ok(grid_block_meta_snapshots +pub(crate) fn make_grid_blocks(block_meta_snapshots: Vec) -> FlowyResult { + Ok(block_meta_snapshots .into_iter() .map(|row_metas_per_block| { - let rows = make_rows_from_row_metas(field_metas, &row_metas_per_block.row_metas); + let row_ids = make_row_ids_from_row_metas(&row_metas_per_block.row_metas); GridBlock { block_id: row_metas_per_block.block_id, - rows, + row_ids, } }) .collect::>() @@ -76,6 +73,10 @@ pub fn make_cell( } } +pub(crate) fn make_row_ids_from_row_metas(row_metas: &Vec>) -> Vec { + row_metas.iter().map(|row_meta| row_meta.id.clone()).collect::>() +} + pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &Vec>) -> Vec { let field_meta_map = fields .iter() @@ -101,22 +102,21 @@ pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &Vec, - grid_block_meta_snapshots: Vec, + block_ids: &[String], + block_meta_data_vec: Vec, ) -> FlowyResult { - let block_meta_snapshot_map: HashMap<&String, &Vec>> = grid_block_meta_snapshots + let block_meta_data_map: HashMap<&String, &Vec>> = block_meta_data_vec .iter() - .map(|snapshot| (&snapshot.block_id, &snapshot.row_metas)) + .map(|data| (&data.block_id, &data.row_metas)) .collect(); let mut grid_blocks = vec![]; - for grid_block_meta in grid_block_metas { - match block_meta_snapshot_map.get(&grid_block_meta.block_id) { + for block_id in block_ids { + match block_meta_data_map.get(&block_id) { None => {} Some(row_metas) => { - let rows = make_rows_from_row_metas(&field_metas, row_metas); - grid_blocks.push(GridBlock::new(&grid_block_meta.block_id, rows)); + let row_ids = make_row_ids_from_row_metas(row_metas); + grid_blocks.push(GridBlock::new(block_id, row_ids)); } } } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 20164bca37..571ca1ab95 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -89,8 +89,8 @@ impl GridEditorTest { let test = ViewTest::new_grid_view(&sdk, view_data.to_vec()).await; let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); let field_metas = editor.get_field_metas(None).await.unwrap(); - let grid_blocks = editor.get_blocks().await.unwrap(); - let row_metas = editor.get_grid_block_meta_snapshots(None).await.unwrap(); + let grid_blocks = editor.get_block_metas().await.unwrap(); + let row_metas = get_row_metas(&editor).await; let grid_id = test.view.id; Self { @@ -150,13 +150,13 @@ impl GridEditorTest { } EditorScript::CreateBlock { block } => { self.editor.create_block(block).await.unwrap(); - self.grid_blocks = self.editor.get_blocks().await.unwrap(); + self.grid_blocks = self.editor.get_block_metas().await.unwrap(); } EditorScript::UpdateBlock { changeset: change } => { self.editor.update_block(change).await.unwrap(); } EditorScript::AssertBlockCount(count) => { - assert_eq!(self.editor.get_blocks().await.unwrap().len(), count); + assert_eq!(self.editor.get_block_metas().await.unwrap().len(), count); } EditorScript::AssertBlock { block_index, @@ -167,25 +167,25 @@ impl GridEditorTest { assert_eq!(self.grid_blocks[block_index].start_row_index, start_row_index); } EditorScript::AssertBlockEqual { block_index, block } => { - let blocks = self.editor.get_blocks().await.unwrap(); + let blocks = self.editor.get_block_metas().await.unwrap(); let compared_block = blocks[block_index].clone(); assert_eq!(compared_block, block); } EditorScript::CreateEmptyRow => { self.editor.create_row(None).await.unwrap(); - self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); - self.grid_blocks = self.editor.get_blocks().await.unwrap(); + self.row_metas = self.get_row_metas().await; + self.grid_blocks = self.editor.get_block_metas().await.unwrap(); } EditorScript::CreateRow { context } => { self.editor.insert_rows(vec![context]).await.unwrap(); - self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); - self.grid_blocks = self.editor.get_blocks().await.unwrap(); + self.row_metas = self.get_row_metas().await; + self.grid_blocks = self.editor.get_block_metas().await.unwrap(); } EditorScript::UpdateRow { changeset: change } => self.editor.update_row(change).await.unwrap(), EditorScript::DeleteRow { row_ids } => { self.editor.delete_rows(row_ids).await.unwrap(); - self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); - self.grid_blocks = self.editor.get_blocks().await.unwrap(); + self.row_metas = self.get_row_metas().await; + self.grid_blocks = self.editor.get_block_metas().await.unwrap(); } EditorScript::AssertRow { changeset } => { let row = self.row_metas.iter().find(|row| row.id == changeset.row_id).unwrap(); @@ -204,11 +204,11 @@ impl GridEditorTest { assert!(result.is_err()) } else { let _ = result.unwrap(); - self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap(); + self.row_metas = self.get_row_metas().await; } } EditorScript::AssertRowCount(count) => { - assert_eq!(self.editor.get_grid_blocks(None).await.unwrap().len(), count); + assert_eq!(self.row_metas.len(), count); } EditorScript::AssertGridMetaPad => { sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await; @@ -218,6 +218,20 @@ impl GridEditorTest { } } } + + async fn get_row_metas(&self) -> Vec> { + get_row_metas(&self.editor).await + } +} + +async fn get_row_metas(editor: &Arc) -> Vec> { + editor + .get_block_meta_data_vec(None) + .await + .unwrap() + .pop() + .unwrap() + .row_metas } pub fn create_text_field() -> FieldMeta { diff --git a/shared-lib/Cargo.lock b/shared-lib/Cargo.lock index 3c859d28f0..a4cde5ddf2 100644 --- a/shared-lib/Cargo.lock +++ b/shared-lib/Cargo.lock @@ -485,6 +485,7 @@ version = "0.1.0" dependencies = [ "bytes", "flowy-derive", + "flowy-error-code", "lib-infra", "protobuf", "serde", diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_data_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_pad.rs similarity index 79% rename from shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_data_pad.rs rename to shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_pad.rs index dd62c787d3..7bfef998c2 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_data_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_block_meta_pad.rs @@ -1,7 +1,7 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{GridBlockMetaData, RowMeta, RowMetaChangeset}; +use flowy_grid_data_model::entities::{GridBlockMetaSerde, RowMeta, RowMetaChangeset}; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use serde::{Deserialize, Serialize}; @@ -12,19 +12,22 @@ pub type GridBlockMetaDelta = PlainTextDelta; pub type GridBlockMetaDeltaBuilder = PlainTextDeltaBuilder; #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct GridBlockMetaDataPad { +pub struct GridBlockMetaPad { block_id: String, - rows: Vec>, + row_metas: Vec>, #[serde(skip)] pub(crate) delta: GridBlockMetaDelta, } -impl GridBlockMetaDataPad { +impl GridBlockMetaPad { pub fn from_delta(delta: GridBlockMetaDelta) -> CollaborateResult { let s = delta.to_str()?; - let block_meta: GridBlockMetaData = serde_json::from_str(&s).map_err(|e| { - CollaborateError::internal().context(format!("Deserialize delta to block meta failed: {}", e)) + tracing::info!("delta: {}", delta); + tracing::info!("{}", s); + let block_meta: GridBlockMetaSerde = serde_json::from_str(&s).map_err(|e| { + let msg = format!("Deserialize delta to block meta failed: {}", e); + CollaborateError::internal().context(msg) })?; let block_id = block_meta.block_id; let rows = block_meta @@ -32,7 +35,11 @@ impl GridBlockMetaDataPad { .into_iter() .map(Arc::new) .collect::>>(); - Ok(Self { block_id, rows, delta }) + Ok(Self { + block_id, + row_metas: rows, + delta, + }) } pub fn from_revisions(_grid_id: &str, revisions: Vec) -> CollaborateResult { @@ -44,7 +51,7 @@ impl GridBlockMetaDataPad { &mut self, row: RowMeta, start_row_id: Option, - ) -> CollaborateResult> { + ) -> CollaborateResult> { self.modify(|rows| { if let Some(upper_row_id) = start_row_id { if upper_row_id.is_empty() { @@ -63,7 +70,7 @@ impl GridBlockMetaDataPad { }) } - pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { + pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult> { self.modify(|rows| { rows.retain(|row| !row_ids.contains(&row.id)); Ok(Some(())) @@ -72,10 +79,10 @@ impl GridBlockMetaDataPad { pub fn get_rows(&self, row_ids: Option>) -> CollaborateResult>> { match row_ids { - None => Ok(self.rows.to_vec()), + None => Ok(self.row_metas.to_vec()), Some(row_ids) => { let row_map = self - .rows + .row_metas .iter() .map(|row| (&row.id, row.clone())) .collect::>>(); @@ -95,10 +102,10 @@ impl GridBlockMetaDataPad { } pub fn number_of_rows(&self) -> i32 { - self.rows.len() as i32 + self.row_metas.len() as i32 } - pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { + pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult> { let row_id = changeset.row_id.clone(); self.modify_row(&row_id, |row| { let mut is_changed = None; @@ -123,12 +130,12 @@ impl GridBlockMetaDataPad { }) } - pub fn modify(&mut self, f: F) -> CollaborateResult> + pub fn modify(&mut self, f: F) -> CollaborateResult> where F: for<'a> FnOnce(&'a mut Vec>) -> CollaborateResult>, { let cloned_self = self.clone(); - match f(&mut self.rows)? { + match f(&mut self.row_metas)? { None => Ok(None), Some(_) => { let old = cloned_self.to_json()?; @@ -137,14 +144,14 @@ impl GridBlockMetaDataPad { None => Ok(None), Some(delta) => { self.delta = self.delta.compose(&delta)?; - Ok(Some(GridBlockMetaDataChange { delta, md5: self.md5() })) + Ok(Some(GridBlockMetaChange { delta, md5: self.md5() })) } } } } } - fn modify_row(&mut self, row_id: &str, f: F) -> CollaborateResult> + fn modify_row(&mut self, row_id: &str, f: F) -> CollaborateResult> where F: FnOnce(&mut RowMeta) -> CollaborateResult>, { @@ -172,35 +179,35 @@ impl GridBlockMetaDataPad { } } -pub struct GridBlockMetaDataChange { +pub struct GridBlockMetaChange { pub delta: GridBlockMetaDelta, /// md5: the md5 of the grid after applying the change. pub md5: String, } -pub fn make_block_meta_delta(grid_block_meta_data: &GridBlockMetaData) -> GridBlockMetaDelta { +pub fn make_block_meta_delta(grid_block_meta_data: &GridBlockMetaSerde) -> GridBlockMetaDelta { let json = serde_json::to_string(&grid_block_meta_data).unwrap(); PlainTextDeltaBuilder::new().insert(&json).build() } -pub fn make_block_meta_revisions(user_id: &str, grid_block_meta_data: &GridBlockMetaData) -> RepeatedRevision { +pub fn make_block_meta_revisions(user_id: &str, grid_block_meta_data: &GridBlockMetaSerde) -> RepeatedRevision { let delta = make_block_meta_delta(grid_block_meta_data); let bytes = delta.to_delta_bytes(); let revision = Revision::initial_revision(user_id, &grid_block_meta_data.block_id, bytes); revision.into() } -impl std::default::Default for GridBlockMetaDataPad { +impl std::default::Default for GridBlockMetaPad { fn default() -> Self { - let block_meta_data = GridBlockMetaData { + let block_meta_data = GridBlockMetaSerde { block_id: uuid(), row_metas: vec![], }; let delta = make_block_meta_delta(&block_meta_data); - GridBlockMetaDataPad { + GridBlockMetaPad { block_id: block_meta_data.block_id, - rows: block_meta_data.row_metas.into_iter().map(Arc::new).collect::>(), + row_metas: block_meta_data.row_metas.into_iter().map(Arc::new).collect::>(), delta, } } @@ -208,7 +215,7 @@ impl std::default::Default for GridBlockMetaDataPad { #[cfg(test)] mod tests { - use crate::client_grid::{GridBlockMetaDataPad, GridBlockMetaDelta}; + use crate::client_grid::{GridBlockMetaDelta, GridBlockMetaPad}; use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset}; #[test] @@ -225,7 +232,7 @@ mod tests { let change = pad.add_row(row, None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + r#"[{"retain":29},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); } @@ -239,27 +246,27 @@ mod tests { let change = pad.add_row(row_1.clone(), None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + r#"[{"retain":29},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); let change = pad.add_row(row_2.clone(), None).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":101},{"insert":",{\"id\":\"2\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# + r#"[{"retain":106},{"insert":",{\"id\":\"2\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"# ); let change = pad.add_row(row_3.clone(), Some("2".to_string())).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":109},{"insert":"3\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false},{\"id\":\""},{"retain":72}]"# + r#"[{"retain":114},{"insert":"3\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false},{\"id\":\""},{"retain":72}]"# ); - assert_eq!(*pad.rows[0], row_1); - assert_eq!(*pad.rows[1], row_3); - assert_eq!(*pad.rows[2], row_2); + assert_eq!(*pad.row_metas[0], row_1); + assert_eq!(*pad.row_metas[1], row_3); + assert_eq!(*pad.row_metas[2], row_2); } - fn test_row_meta(id: &str, pad: &GridBlockMetaDataPad) -> RowMeta { + fn test_row_meta(id: &str, pad: &GridBlockMetaPad) -> RowMeta { RowMeta { id: id.to_string(), block_id: pad.block_id.clone(), @@ -280,9 +287,9 @@ mod tests { let _ = pad.add_row(row_2.clone(), None).unwrap().unwrap(); let _ = pad.add_row(row_3.clone(), Some("1".to_string())).unwrap().unwrap(); - assert_eq!(*pad.rows[0], row_3); - assert_eq!(*pad.rows[1], row_1); - assert_eq!(*pad.rows[2], row_2); + assert_eq!(*pad.row_metas[0], row_3); + assert_eq!(*pad.row_metas[1], row_1); + assert_eq!(*pad.row_metas[2], row_2); } #[test] @@ -296,9 +303,9 @@ mod tests { let _ = pad.add_row(row_2.clone(), None).unwrap().unwrap(); let _ = pad.add_row(row_3.clone(), Some("".to_string())).unwrap().unwrap(); - assert_eq!(*pad.rows[0], row_3); - assert_eq!(*pad.rows[1], row_1); - assert_eq!(*pad.rows[2], row_2); + assert_eq!(*pad.row_metas[0], row_3); + assert_eq!(*pad.row_metas[1], row_1); + assert_eq!(*pad.row_metas[2], row_2); } #[test] @@ -317,7 +324,7 @@ mod tests { let change = pad.delete_rows(&[row.id]).unwrap().unwrap(); assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":24},{"delete":77},{"retain":2}]"# + r#"[{"retain":29},{"delete":77},{"retain":2}]"# ); assert_eq!(pad.delta_str(), pre_delta_str); @@ -346,17 +353,18 @@ mod tests { assert_eq!( change.delta.to_delta_str(), - r#"[{"retain":80},{"insert":"10"},{"retain":15},{"insert":"tru"},{"delete":4},{"retain":4}]"# + r#"[{"retain":85},{"insert":"10"},{"retain":15},{"insert":"tru"},{"delete":4},{"retain":4}]"# ); assert_eq!( pad.to_json().unwrap(), - r#"{"block_id":"1","rows":[{"id":"1","block_id":"1","cell_by_field_id":{},"height":100,"visibility":true}]}"# + r#"{"block_id":"1","row_metas":[{"id":"1","block_id":"1","cell_by_field_id":{},"height":100,"visibility":true}]}"# ); } - fn test_pad() -> GridBlockMetaDataPad { - let delta = GridBlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap(); - GridBlockMetaDataPad::from_delta(delta).unwrap() + fn test_pad() -> GridBlockMetaPad { + let delta = + GridBlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"row_metas\":[]}"}]"#).unwrap(); + GridBlockMetaPad::from_delta(delta).unwrap() } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index 3eb8af06c3..2875a8968c 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -13,9 +13,9 @@ impl GridBuilder { } pub fn add_empty_row(mut self) -> Self { - let row = RowMeta::new(&self.build_context.grid_block.block_id); - self.build_context.grid_block_meta_data.row_metas.push(row); - self.build_context.grid_block.row_count += 1; + let row = RowMeta::new(&self.build_context.block_metas.block_id); + self.build_context.block_meta_data.row_metas.push(row); + self.build_context.block_metas.row_count += 1; self } @@ -41,7 +41,7 @@ fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> { mod tests { use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBuilder}; - use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMetaData, GridMeta}; + use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMetaSerde, GridMeta}; #[test] fn create_default_grid_test() { @@ -57,13 +57,13 @@ mod tests { let grid_meta = GridMeta { grid_id, fields: build_context.field_metas, - blocks: vec![build_context.grid_block], + block_metas: vec![build_context.block_metas], }; let grid_meta_delta = make_grid_delta(&grid_meta); let _: GridMeta = serde_json::from_str(&grid_meta_delta.to_str().unwrap()).unwrap(); - let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta_data); - let _: GridBlockMetaData = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap(); + let grid_block_meta_delta = make_block_meta_delta(&build_context.block_meta_data); + let _: GridBlockMetaSerde = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap(); } } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs index 31c6ed0fbf..8d4ab37b6d 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_meta_pad.rs @@ -140,12 +140,12 @@ impl GridMetaPad { pub fn create_block(&mut self, block: GridBlockMeta) -> CollaborateResult> { self.modify_grid(|grid| { - if grid.blocks.iter().any(|b| b.block_id == block.block_id) { + if grid.block_metas.iter().any(|b| b.block_id == block.block_id) { tracing::warn!("Duplicate grid block"); Ok(None) } else { - match grid.blocks.last() { - None => grid.blocks.push(block), + match grid.block_metas.last() { + None => grid.block_metas.push(block), Some(last_block) => { if last_block.start_row_index > block.start_row_index && last_block.len() > block.start_row_index @@ -153,7 +153,7 @@ impl GridMetaPad { let msg = "GridBlock's start_row_index should be greater than the last_block's start_row_index and its len".to_string(); return Err(CollaborateError::internal().context(msg)) } - grid.blocks.push(block); + grid.block_metas.push(block); } } Ok(Some(())) @@ -162,7 +162,7 @@ impl GridMetaPad { } pub fn get_blocks(&self) -> Vec { - self.grid_meta.blocks.clone() + self.grid_meta.block_metas.clone() } pub fn update_block(&mut self, changeset: GridBlockMetaChangeset) -> CollaborateResult> { @@ -226,12 +226,12 @@ impl GridMetaPad { F: FnOnce(&mut GridBlockMeta) -> CollaborateResult>, { self.modify_grid( - |grid| match grid.blocks.iter().position(|block| block.block_id == block_id) { + |grid| match grid.block_metas.iter().position(|block| block.block_id == block_id) { None => { tracing::warn!("[GridMetaPad]: Can't find any block with id: {}", block_id); Ok(None) } - Some(index) => f(&mut grid.blocks[index]), + Some(index) => f(&mut grid.block_metas[index]), }, ) } @@ -279,7 +279,7 @@ impl std::default::Default for GridMetaPad { let grid = GridMeta { grid_id: uuid(), fields: vec![], - blocks: vec![], + block_metas: vec![], }; let delta = make_grid_delta(&grid); GridMetaPad { diff --git a/shared-lib/flowy-collaboration/src/client_grid/mod.rs b/shared-lib/flowy-collaboration/src/client_grid/mod.rs index f41d3601b4..5df06e7858 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/mod.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/mod.rs @@ -1,7 +1,7 @@ -mod grid_block_meta_data_pad; +mod grid_block_meta_pad; mod grid_builder; mod grid_meta_pad; -pub use grid_block_meta_data_pad::*; +pub use grid_block_meta_pad::*; pub use grid_builder::*; pub use grid_meta_pad::*; diff --git a/shared-lib/flowy-error-code/src/code.rs b/shared-lib/flowy-error-code/src/code.rs index 166202bd5b..e184fd41bf 100644 --- a/shared-lib/flowy-error-code/src/code.rs +++ b/shared-lib/flowy-error-code/src/code.rs @@ -85,8 +85,14 @@ pub enum ErrorCode { UserNotExist = 312, #[display(fmt = "Text is too long")] TextTooLong = 400, + #[display(fmt = "Grid block id is empty")] + BlockIdIsEmpty = 401, + #[display(fmt = "Row id is empty")] + RowIdIsEmpty = 402, + #[display(fmt = "Grid id is empty")] + GridIdIsEmpty = 403, #[display(fmt = "Invalid data")] - InvalidData = 401, + InvalidData = 404, } impl ErrorCode { diff --git a/shared-lib/flowy-error-code/src/protobuf/model/code.rs b/shared-lib/flowy-error-code/src/protobuf/model/code.rs index 769c059eb2..85a0721d7c 100644 --- a/shared-lib/flowy-error-code/src/protobuf/model/code.rs +++ b/shared-lib/flowy-error-code/src/protobuf/model/code.rs @@ -56,7 +56,10 @@ pub enum ErrorCode { UserIdInvalid = 311, UserNotExist = 312, TextTooLong = 400, - InvalidData = 401, + BlockIdIsEmpty = 401, + RowIdIsEmpty = 402, + GridIdIsEmpty = 403, + InvalidData = 404, } impl ::protobuf::ProtobufEnum for ErrorCode { @@ -97,7 +100,10 @@ impl ::protobuf::ProtobufEnum for ErrorCode { 311 => ::std::option::Option::Some(ErrorCode::UserIdInvalid), 312 => ::std::option::Option::Some(ErrorCode::UserNotExist), 400 => ::std::option::Option::Some(ErrorCode::TextTooLong), - 401 => ::std::option::Option::Some(ErrorCode::InvalidData), + 401 => ::std::option::Option::Some(ErrorCode::BlockIdIsEmpty), + 402 => ::std::option::Option::Some(ErrorCode::RowIdIsEmpty), + 403 => ::std::option::Option::Some(ErrorCode::GridIdIsEmpty), + 404 => ::std::option::Option::Some(ErrorCode::InvalidData), _ => ::std::option::Option::None } } @@ -135,6 +141,9 @@ impl ::protobuf::ProtobufEnum for ErrorCode { ErrorCode::UserIdInvalid, ErrorCode::UserNotExist, ErrorCode::TextTooLong, + ErrorCode::BlockIdIsEmpty, + ErrorCode::RowIdIsEmpty, + ErrorCode::GridIdIsEmpty, ErrorCode::InvalidData, ]; values @@ -164,7 +173,7 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ncode.proto*\xe8\x05\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ + \n\ncode.proto*\xa4\x06\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\ \n\x10UserUnauthorized\x10\x02\x12\x12\n\x0eRecordNotFound\x10\x03\x12\ \x18\n\x14WorkspaceNameInvalid\x10d\x12\x16\n\x12WorkspaceIdInvalid\x10e\ \x12\x18\n\x14AppColorStyleInvalid\x10f\x12\x18\n\x14WorkspaceDescTooLon\ @@ -181,8 +190,9 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x14\n\x0fUserNameTooLong\x10\xb4\x02\x12'\n\"UserNameContainForbiddenCh\ aracters\x10\xb5\x02\x12\x14\n\x0fUserNameIsEmpty\x10\xb6\x02\x12\x12\n\ \rUserIdInvalid\x10\xb7\x02\x12\x11\n\x0cUserNotExist\x10\xb8\x02\x12\ - \x10\n\x0bTextTooLong\x10\x90\x03\x12\x10\n\x0bInvalidData\x10\x91\x03b\ - \x06proto3\ + \x10\n\x0bTextTooLong\x10\x90\x03\x12\x13\n\x0eBlockIdIsEmpty\x10\x91\ + \x03\x12\x11\n\x0cRowIdIsEmpty\x10\x92\x03\x12\x12\n\rGridIdIsEmpty\x10\ + \x93\x03\x12\x10\n\x0bInvalidData\x10\x94\x03b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto index 4bf692b8ff..7015c1fe38 100644 --- a/shared-lib/flowy-error-code/src/protobuf/proto/code.proto +++ b/shared-lib/flowy-error-code/src/protobuf/proto/code.proto @@ -32,5 +32,8 @@ enum ErrorCode { UserIdInvalid = 311; UserNotExist = 312; TextTooLong = 400; - InvalidData = 401; + BlockIdIsEmpty = 401; + RowIdIsEmpty = 402; + GridIdIsEmpty = 403; + InvalidData = 404; } diff --git a/shared-lib/flowy-grid-data-model/Cargo.toml b/shared-lib/flowy-grid-data-model/Cargo.toml index c0e5bb91bc..89461b444c 100644 --- a/shared-lib/flowy-grid-data-model/Cargo.toml +++ b/shared-lib/flowy-grid-data-model/Cargo.toml @@ -14,6 +14,7 @@ strum_macros = "0.21" serde = { version = "1.0", features = ["derive"] } serde_json = {version = "1.0"} uuid = { version = "0.8", features = ["serde", "v4"] } +flowy-error-code = { path = "../flowy-error-code"} [build-dependencies] lib-infra = { path = "../lib-infra", features = ["protobuf_file_gen"] } 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 95a0454eb1..48aa574298 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,7 +1,9 @@ -use crate::entities::{FieldMeta, FieldType, GridBlockMeta, RowMeta}; +use crate::entities::{FieldMeta, FieldType, RowMeta}; use flowy_derive::ProtoBuf; use std::collections::HashMap; -use std::hash::Hash; + +use crate::parser::NonEmptyId; +use flowy_error_code::ErrorCode; use std::sync::Arc; #[derive(Debug, Clone, Default, ProtoBuf)] @@ -13,7 +15,7 @@ pub struct Grid { pub field_orders: Vec, #[pb(index = 3)] - pub blocks: Vec, + pub block_orders: Vec, } #[derive(Debug, Clone, Default, ProtoBuf)] @@ -169,6 +171,18 @@ pub struct Row { pub height: i32, } +#[derive(Debug, Default, ProtoBuf)] +pub struct RepeatedRow { + #[pb(index = 1)] + pub items: Vec, +} + +impl std::convert::From> for RepeatedRow { + fn from(items: Vec) -> Self { + Self { items } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedGridBlock { #[pb(index = 1)] @@ -181,20 +195,26 @@ impl std::convert::From> for RepeatedGridBlock { } } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct GridBlockOrder { + #[pb(index = 1)] + pub block_id: String, +} + #[derive(Debug, Default, ProtoBuf)] pub struct GridBlock { #[pb(index = 1)] pub block_id: String, #[pb(index = 2)] - pub rows: Vec, + pub row_ids: Vec, } impl GridBlock { - pub fn new(block_id: &str, rows: Vec) -> Self { + pub fn new(block_id: &str, row_ids: Vec) -> Self { Self { block_id: block_id.to_owned(), - rows, + row_ids, } } } @@ -278,7 +298,7 @@ pub struct CreateRowPayload { pub grid_id: String, #[pb(index = 2, one_of)] - pub upper_row_id: Option, + pub start_row_id: Option, } #[derive(ProtoBuf, Default)] @@ -296,5 +316,17 @@ pub struct QueryGridBlocksPayload { pub grid_id: String, #[pb(index = 2)] - pub blocks: Vec, + pub block_orders: Vec, +} + +#[derive(ProtoBuf, Default)] +pub struct QueryRowPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub block_id: String, + + #[pb(index = 3)] + pub row_id: String, } diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 62a545fcb0..c7c621d7ec 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -2,6 +2,7 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; +use crate::entities::GridBlockOrder; use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 36; @@ -16,7 +17,7 @@ pub struct GridMeta { pub fields: Vec, #[pb(index = 3)] - pub blocks: Vec, + pub block_metas: Vec, } #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] @@ -33,7 +34,7 @@ pub struct GridBlockMeta { impl GridBlockMeta { pub fn len(&self) -> i32 { - self.start_row_index + self.row_count + self.row_count } pub fn is_empty(&self) -> bool { @@ -67,7 +68,7 @@ impl GridBlockMetaChangeset { } #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] -pub struct GridBlockMetaData { +pub struct GridBlockMetaSerde { #[pb(index = 1)] pub block_id: String, @@ -329,24 +330,24 @@ pub struct BuildGridContext { pub field_metas: Vec, #[pb(index = 2)] - pub grid_block: GridBlockMeta, + pub block_metas: GridBlockMeta, #[pb(index = 3)] - pub grid_block_meta_data: GridBlockMetaData, + pub block_meta_data: GridBlockMetaSerde, } impl std::default::Default for BuildGridContext { fn default() -> Self { let grid_block = GridBlockMeta::new(); - let grid_block_meta_data = GridBlockMetaData { + let grid_block_meta_data = GridBlockMetaSerde { block_id: grid_block.block_id.clone(), row_metas: vec![], }; Self { field_metas: vec![], - grid_block, - grid_block_meta_data, + block_metas: grid_block, + block_meta_data: grid_block_meta_data, } } } diff --git a/shared-lib/flowy-grid-data-model/src/lib.rs b/shared-lib/flowy-grid-data-model/src/lib.rs index 85976edd74..bd9ed4465e 100644 --- a/shared-lib/flowy-grid-data-model/src/lib.rs +++ b/shared-lib/flowy-grid-data-model/src/lib.rs @@ -1,2 +1,3 @@ pub mod entities; +pub mod parser; pub mod protobuf; diff --git a/shared-lib/flowy-grid-data-model/src/parser/grid.rs b/shared-lib/flowy-grid-data-model/src/parser/grid.rs new file mode 100644 index 0000000000..49a202cf70 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/parser/grid.rs @@ -0,0 +1,82 @@ +use crate::entities::{ + CreateRowPayload, GridBlockOrder, QueryFieldPayload, QueryGridBlocksPayload, QueryRowPayload, RepeatedFieldOrder, +}; +use crate::parser::NonEmptyId; +use flowy_error_code::ErrorCode; + +#[derive(Default)] +pub struct CreateRowParams { + pub grid_id: String, + pub start_row_id: Option, +} + +impl TryInto for CreateRowPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + Ok(CreateRowParams { + grid_id: grid_id.0, + start_row_id: self.start_row_id, + }) + } +} + +#[derive(Default)] +pub struct QueryFieldParams { + pub grid_id: String, + pub field_orders: RepeatedFieldOrder, +} + +impl TryInto for QueryFieldPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + Ok(QueryFieldParams { + grid_id: grid_id.0, + field_orders: self.field_orders, + }) + } +} + +#[derive(Default)] +pub struct QueryGridBlocksParams { + pub grid_id: String, + pub block_orders: Vec, +} + +impl TryInto for QueryGridBlocksPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + Ok(QueryGridBlocksParams { + grid_id: grid_id.0, + block_orders: self.block_orders, + }) + } +} + +#[derive(Default)] +pub struct QueryRowParams { + pub grid_id: String, + pub block_id: String, + pub row_id: String, +} + +impl TryInto for QueryRowPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let block_id = NonEmptyId::parse(self.block_id).map_err(|_| ErrorCode::BlockIdIsEmpty)?; + let row_id = NonEmptyId::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; + + Ok(QueryRowParams { + grid_id: grid_id.0, + block_id: block_id.0, + row_id: row_id.0, + }) + } +} diff --git a/shared-lib/flowy-grid-data-model/src/parser/id.rs b/shared-lib/flowy-grid-data-model/src/parser/id.rs new file mode 100644 index 0000000000..0f35fbfef5 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/parser/id.rs @@ -0,0 +1,20 @@ +use flowy_error_code::ErrorCode; + +#[derive(Debug)] +pub struct NonEmptyId(pub String); + +impl NonEmptyId { + pub fn parse(s: String) -> Result { + if s.trim().is_empty() { + return Err(()); + } + + Ok(Self(s)) + } +} + +impl AsRef for NonEmptyId { + fn as_ref(&self) -> &str { + &self.0 + } +} diff --git a/shared-lib/flowy-grid-data-model/src/parser/mod.rs b/shared-lib/flowy-grid-data-model/src/parser/mod.rs new file mode 100644 index 0000000000..ec81801043 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/parser/mod.rs @@ -0,0 +1,5 @@ +mod grid; +mod id; + +pub use grid::*; +pub use id::*; 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 6e76d92a7c..630e109891 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 @@ -28,7 +28,7 @@ pub struct Grid { // message fields pub id: ::std::string::String, pub field_orders: ::protobuf::RepeatedField, - pub blocks: ::protobuf::RepeatedField, + pub block_orders: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -96,29 +96,29 @@ impl Grid { ::std::mem::replace(&mut self.field_orders, ::protobuf::RepeatedField::new()) } - // repeated .GridBlockMeta blocks = 3; + // repeated .GridBlockOrder block_orders = 3; - pub fn get_blocks(&self) -> &[super::meta::GridBlockMeta] { - &self.blocks + pub fn get_block_orders(&self) -> &[GridBlockOrder] { + &self.block_orders } - pub fn clear_blocks(&mut self) { - self.blocks.clear(); + pub fn clear_block_orders(&mut self) { + self.block_orders.clear(); } // Param is passed by value, moved - pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { - self.blocks = v; + pub fn set_block_orders(&mut self, v: ::protobuf::RepeatedField) { + self.block_orders = v; } // Mutable pointer to the field. - pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.blocks + pub fn mut_block_orders(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.block_orders } // Take field - pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) + pub fn take_block_orders(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.block_orders, ::protobuf::RepeatedField::new()) } } @@ -129,7 +129,7 @@ impl ::protobuf::Message for Grid { return false; } }; - for v in &self.blocks { + for v in &self.block_orders { if !v.is_initialized() { return false; } @@ -148,7 +148,7 @@ impl ::protobuf::Message for Grid { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.field_orders)?; }, 3 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.block_orders)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -169,7 +169,7 @@ impl ::protobuf::Message for Grid { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; - for value in &self.blocks { + for value in &self.block_orders { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; @@ -187,7 +187,7 @@ impl ::protobuf::Message for Grid { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; }; - for v in &self.blocks { + for v in &self.block_orders { os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -240,10 +240,10 @@ impl ::protobuf::Message for Grid { |m: &Grid| { &m.field_orders }, |m: &mut Grid| { &mut m.field_orders }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "blocks", - |m: &Grid| { &m.blocks }, - |m: &mut Grid| { &mut m.blocks }, + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "block_orders", + |m: &Grid| { &m.block_orders }, + |m: &mut Grid| { &mut m.block_orders }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "Grid", @@ -263,7 +263,7 @@ impl ::protobuf::Clear for Grid { fn clear(&mut self) { self.id.clear(); self.field_orders.clear(); - self.blocks.clear(); + self.block_orders.clear(); self.unknown_fields.clear(); } } @@ -1748,6 +1748,172 @@ impl ::protobuf::reflect::ProtobufValue for Row { } } +#[derive(PartialEq,Clone,Default)] +pub struct RepeatedRow { + // message fields + pub items: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a RepeatedRow { + fn default() -> &'a RepeatedRow { + ::default_instance() + } +} + +impl RepeatedRow { + pub fn new() -> RepeatedRow { + ::std::default::Default::default() + } + + // repeated .Row items = 1; + + + pub fn get_items(&self) -> &[Row] { + &self.items + } + pub fn clear_items(&mut self) { + self.items.clear(); + } + + // Param is passed by value, moved + pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { + self.items = v; + } + + // Mutable pointer to the field. + pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.items + } + + // Take field + pub fn take_items(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for RepeatedRow { + fn is_initialized(&self) -> bool { + for v in &self.items { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.items { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + for v in &self.items { + os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> RepeatedRow { + RepeatedRow::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "items", + |m: &RepeatedRow| { &m.items }, + |m: &mut RepeatedRow| { &mut m.items }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedRow", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RepeatedRow { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedRow::new) + } +} + +impl ::protobuf::Clear for RepeatedRow { + fn clear(&mut self) { + self.items.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RepeatedRow { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RepeatedRow { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct RepeatedGridBlock { // message fields @@ -1914,11 +2080,170 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedGridBlock { } } +#[derive(PartialEq,Clone,Default)] +pub struct GridBlockOrder { + // message fields + pub block_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridBlockOrder { + fn default() -> &'a GridBlockOrder { + ::default_instance() + } +} + +impl GridBlockOrder { + pub fn new() -> GridBlockOrder { + ::std::default::Default::default() + } + + // string block_id = 1; + + + pub fn get_block_id(&self) -> &str { + &self.block_id + } + pub fn clear_block_id(&mut self) { + self.block_id.clear(); + } + + // Param is passed by value, moved + pub fn set_block_id(&mut self, v: ::std::string::String) { + self.block_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id + } + + // Take field + pub fn take_block_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for GridBlockOrder { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.block_id); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.block_id.is_empty() { + os.write_string(1, &self.block_id)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> GridBlockOrder { + GridBlockOrder::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "block_id", + |m: &GridBlockOrder| { &m.block_id }, + |m: &mut GridBlockOrder| { &mut m.block_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlockOrder", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridBlockOrder { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlockOrder::new) + } +} + +impl ::protobuf::Clear for GridBlockOrder { + fn clear(&mut self) { + self.block_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridBlockOrder { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridBlockOrder { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct GridBlock { // message fields pub block_id: ::std::string::String, - pub rows: ::protobuf::RepeatedField, + pub row_ids: ::protobuf::RepeatedField<::std::string::String>, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -1961,39 +2286,34 @@ impl GridBlock { ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) } - // repeated .Row rows = 2; + // repeated string row_ids = 2; - pub fn get_rows(&self) -> &[Row] { - &self.rows + pub fn get_row_ids(&self) -> &[::std::string::String] { + &self.row_ids } - pub fn clear_rows(&mut self) { - self.rows.clear(); + pub fn clear_row_ids(&mut self) { + self.row_ids.clear(); } // Param is passed by value, moved - pub fn set_rows(&mut self, v: ::protobuf::RepeatedField) { - self.rows = v; + pub fn set_row_ids(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) { + self.row_ids = v; } // Mutable pointer to the field. - pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.rows + pub fn mut_row_ids(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> { + &mut self.row_ids } // Take field - pub fn take_rows(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new()) + pub fn take_row_ids(&mut self) -> ::protobuf::RepeatedField<::std::string::String> { + ::std::mem::replace(&mut self.row_ids, ::protobuf::RepeatedField::new()) } } impl ::protobuf::Message for GridBlock { fn is_initialized(&self) -> bool { - for v in &self.rows { - if !v.is_initialized() { - return false; - } - }; true } @@ -2005,7 +2325,7 @@ impl ::protobuf::Message for GridBlock { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, 2 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?; + ::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.row_ids)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -2022,9 +2342,8 @@ impl ::protobuf::Message for GridBlock { if !self.block_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.block_id); } - for value in &self.rows { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + for value in &self.row_ids { + my_size += ::protobuf::rt::string_size(2, &value); }; my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -2035,10 +2354,8 @@ impl ::protobuf::Message for GridBlock { if !self.block_id.is_empty() { os.write_string(1, &self.block_id)?; } - for v in &self.rows { - os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; + for v in &self.row_ids { + os.write_string(2, &v)?; }; os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -2083,10 +2400,10 @@ impl ::protobuf::Message for GridBlock { |m: &GridBlock| { &m.block_id }, |m: &mut GridBlock| { &mut m.block_id }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "rows", - |m: &GridBlock| { &m.rows }, - |m: &mut GridBlock| { &mut m.rows }, + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_ids", + |m: &GridBlock| { &m.row_ids }, + |m: &mut GridBlock| { &mut m.row_ids }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "GridBlock", @@ -2105,7 +2422,7 @@ impl ::protobuf::Message for GridBlock { impl ::protobuf::Clear for GridBlock { fn clear(&mut self) { self.block_id.clear(); - self.rows.clear(); + self.row_ids.clear(); self.unknown_fields.clear(); } } @@ -2971,7 +3288,7 @@ pub struct CreateRowPayload { // message fields pub grid_id: ::std::string::String, // message oneof groups - pub one_of_upper_row_id: ::std::option::Option, + pub one_of_start_row_id: ::std::option::Option, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -2984,8 +3301,8 @@ impl<'a> ::std::default::Default for &'a CreateRowPayload { } #[derive(Clone,PartialEq,Debug)] -pub enum CreateRowPayload_oneof_one_of_upper_row_id { - upper_row_id(::std::string::String), +pub enum CreateRowPayload_oneof_one_of_start_row_id { + start_row_id(::std::string::String), } impl CreateRowPayload { @@ -3019,48 +3336,48 @@ impl CreateRowPayload { ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) } - // string upper_row_id = 2; + // string start_row_id = 2; - pub fn get_upper_row_id(&self) -> &str { - match self.one_of_upper_row_id { - ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref v)) => v, + pub fn get_start_row_id(&self) -> &str { + match self.one_of_start_row_id { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(ref v)) => v, _ => "", } } - pub fn clear_upper_row_id(&mut self) { - self.one_of_upper_row_id = ::std::option::Option::None; + pub fn clear_start_row_id(&mut self) { + self.one_of_start_row_id = ::std::option::Option::None; } - pub fn has_upper_row_id(&self) -> bool { - match self.one_of_upper_row_id { - ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(..)) => true, + pub fn has_start_row_id(&self) -> bool { + match self.one_of_start_row_id { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(..)) => true, _ => false, } } // Param is passed by value, moved - pub fn set_upper_row_id(&mut self, v: ::std::string::String) { - self.one_of_upper_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(v)) + pub fn set_start_row_id(&mut self, v: ::std::string::String) { + self.one_of_start_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(v)) } // Mutable pointer to the field. - pub fn mut_upper_row_id(&mut self) -> &mut ::std::string::String { - if let ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(_)) = self.one_of_upper_row_id { + pub fn mut_start_row_id(&mut self) -> &mut ::std::string::String { + if let ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(_)) = self.one_of_start_row_id { } else { - self.one_of_upper_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(::std::string::String::new())); + self.one_of_start_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(::std::string::String::new())); } - match self.one_of_upper_row_id { - ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref mut v)) => v, + match self.one_of_start_row_id { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(ref mut v)) => v, _ => panic!(), } } // Take field - pub fn take_upper_row_id(&mut self) -> ::std::string::String { - if self.has_upper_row_id() { - match self.one_of_upper_row_id.take() { - ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(v)) => v, + pub fn take_start_row_id(&mut self) -> ::std::string::String { + if self.has_start_row_id() { + match self.one_of_start_row_id.take() { + ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(v)) => v, _ => panic!(), } } else { @@ -3085,7 +3402,7 @@ impl ::protobuf::Message for CreateRowPayload { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } - self.one_of_upper_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(is.read_string()?)); + self.one_of_start_row_id = ::std::option::Option::Some(CreateRowPayload_oneof_one_of_start_row_id::start_row_id(is.read_string()?)); }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -3102,9 +3419,9 @@ impl ::protobuf::Message for CreateRowPayload { if !self.grid_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.grid_id); } - if let ::std::option::Option::Some(ref v) = self.one_of_upper_row_id { + if let ::std::option::Option::Some(ref v) = self.one_of_start_row_id { match v { - &CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref v) => { + &CreateRowPayload_oneof_one_of_start_row_id::start_row_id(ref v) => { my_size += ::protobuf::rt::string_size(2, &v); }, }; @@ -3118,9 +3435,9 @@ impl ::protobuf::Message for CreateRowPayload { if !self.grid_id.is_empty() { os.write_string(1, &self.grid_id)?; } - if let ::std::option::Option::Some(ref v) = self.one_of_upper_row_id { + if let ::std::option::Option::Some(ref v) = self.one_of_start_row_id { match v { - &CreateRowPayload_oneof_one_of_upper_row_id::upper_row_id(ref v) => { + &CreateRowPayload_oneof_one_of_start_row_id::start_row_id(ref v) => { os.write_string(2, v)?; }, }; @@ -3169,9 +3486,9 @@ impl ::protobuf::Message for CreateRowPayload { |m: &mut CreateRowPayload| { &mut m.grid_id }, )); fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( - "upper_row_id", - CreateRowPayload::has_upper_row_id, - CreateRowPayload::get_upper_row_id, + "start_row_id", + CreateRowPayload::has_start_row_id, + CreateRowPayload::get_start_row_id, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "CreateRowPayload", @@ -3190,7 +3507,7 @@ impl ::protobuf::Message for CreateRowPayload { impl ::protobuf::Clear for CreateRowPayload { fn clear(&mut self) { self.grid_id.clear(); - self.one_of_upper_row_id = ::std::option::Option::None; + self.one_of_start_row_id = ::std::option::Option::None; self.unknown_fields.clear(); } } @@ -3427,7 +3744,7 @@ impl ::protobuf::reflect::ProtobufValue for QueryFieldPayload { pub struct QueryGridBlocksPayload { // message fields pub grid_id: ::std::string::String, - pub blocks: ::protobuf::RepeatedField, + pub block_orders: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -3470,35 +3787,35 @@ impl QueryGridBlocksPayload { ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) } - // repeated .GridBlockMeta blocks = 2; + // repeated .GridBlockOrder block_orders = 2; - pub fn get_blocks(&self) -> &[super::meta::GridBlockMeta] { - &self.blocks + pub fn get_block_orders(&self) -> &[GridBlockOrder] { + &self.block_orders } - pub fn clear_blocks(&mut self) { - self.blocks.clear(); + pub fn clear_block_orders(&mut self) { + self.block_orders.clear(); } // Param is passed by value, moved - pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { - self.blocks = v; + pub fn set_block_orders(&mut self, v: ::protobuf::RepeatedField) { + self.block_orders = v; } // Mutable pointer to the field. - pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.blocks + pub fn mut_block_orders(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.block_orders } // Take field - pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) + pub fn take_block_orders(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.block_orders, ::protobuf::RepeatedField::new()) } } impl ::protobuf::Message for QueryGridBlocksPayload { fn is_initialized(&self) -> bool { - for v in &self.blocks { + for v in &self.block_orders { if !v.is_initialized() { return false; } @@ -3514,7 +3831,7 @@ impl ::protobuf::Message for QueryGridBlocksPayload { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; }, 2 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.block_orders)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -3531,7 +3848,7 @@ impl ::protobuf::Message for QueryGridBlocksPayload { if !self.grid_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.grid_id); } - for value in &self.blocks { + for value in &self.block_orders { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; @@ -3544,7 +3861,7 @@ impl ::protobuf::Message for QueryGridBlocksPayload { if !self.grid_id.is_empty() { os.write_string(1, &self.grid_id)?; } - for v in &self.blocks { + for v in &self.block_orders { os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -3592,10 +3909,10 @@ impl ::protobuf::Message for QueryGridBlocksPayload { |m: &QueryGridBlocksPayload| { &m.grid_id }, |m: &mut QueryGridBlocksPayload| { &mut m.grid_id }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "blocks", - |m: &QueryGridBlocksPayload| { &m.blocks }, - |m: &mut QueryGridBlocksPayload| { &mut m.blocks }, + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "block_orders", + |m: &QueryGridBlocksPayload| { &m.block_orders }, + |m: &mut QueryGridBlocksPayload| { &mut m.block_orders }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "QueryGridBlocksPayload", @@ -3614,7 +3931,7 @@ impl ::protobuf::Message for QueryGridBlocksPayload { impl ::protobuf::Clear for QueryGridBlocksPayload { fn clear(&mut self) { self.grid_id.clear(); - self.blocks.clear(); + self.block_orders.clear(); self.unknown_fields.clear(); } } @@ -3631,43 +3948,291 @@ impl ::protobuf::reflect::ProtobufValue for QueryGridBlocksPayload { } } +#[derive(PartialEq,Clone,Default)] +pub struct QueryRowPayload { + // message fields + pub grid_id: ::std::string::String, + pub block_id: ::std::string::String, + pub row_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a QueryRowPayload { + fn default() -> &'a QueryRowPayload { + ::default_instance() + } +} + +impl QueryRowPayload { + pub fn new() -> QueryRowPayload { + ::std::default::Default::default() + } + + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // string block_id = 2; + + + pub fn get_block_id(&self) -> &str { + &self.block_id + } + pub fn clear_block_id(&mut self) { + self.block_id.clear(); + } + + // Param is passed by value, moved + pub fn set_block_id(&mut self, v: ::std::string::String) { + self.block_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id + } + + // Take field + pub fn take_block_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) + } + + // string row_id = 3; + + + pub fn get_row_id(&self) -> &str { + &self.row_id + } + pub fn clear_row_id(&mut self) { + self.row_id.clear(); + } + + // Param is passed by value, moved + pub fn set_row_id(&mut self, v: ::std::string::String) { + self.row_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_id(&mut self) -> &mut ::std::string::String { + &mut self.row_id + } + + // Take field + pub fn take_row_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for QueryRowPayload { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.block_id); + } + if !self.row_id.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.row_id); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if !self.block_id.is_empty() { + os.write_string(2, &self.block_id)?; + } + if !self.row_id.is_empty() { + os.write_string(3, &self.row_id)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> QueryRowPayload { + QueryRowPayload::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &QueryRowPayload| { &m.grid_id }, + |m: &mut QueryRowPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "block_id", + |m: &QueryRowPayload| { &m.block_id }, + |m: &mut QueryRowPayload| { &mut m.block_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &QueryRowPayload| { &m.row_id }, + |m: &mut QueryRowPayload| { &mut m.row_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "QueryRowPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static QueryRowPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(QueryRowPayload::new) + } +} + +impl ::protobuf::Clear for QueryRowPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.block_id.clear(); + self.row_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for QueryRowPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for QueryRowPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ngrid.proto\x1a\nmeta.proto\"n\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\ + \n\ngrid.proto\x1a\nmeta.proto\"z\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\ \x01(\tR\x02id\x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrd\ - erR\x0bfieldOrders\x12&\n\x06blocks\x18\x03\x20\x03(\x0b2\x0e.GridBlockM\ - etaR\x06blocks\"\xb8\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ - \x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ - \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\ - FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ - n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ - idth\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\x19\n\x08field_\ - id\x18\x01\x20\x01(\tR\x07fieldId\"-\n\rRepeatedField\x12\x1c\n\x05items\ - \x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFieldOrder\ - \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"<\n\x08\ - RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08b\ - lock_id\x18\x02\x20\x01(\tR\x07blockId\"3\n\x10RepeatedRowOrder\x12\x1f\ - \n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05items\"\xb8\x01\n\x03Ro\ - w\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\ - \x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\ - \x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldId\ - Entry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\ - \x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\"5\n\x11RepeatedGridBloc\ - k\x12\x20\n\x05items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"@\n\tG\ - ridBlock\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x18\n\ - \x04rows\x18\x02\x20\x03(\x0b2\x04.RowR\x04rows\";\n\x04Cell\x12\x19\n\ - \x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\ - \x20\x01(\tR\x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\ - \x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\ - \x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05valu\ - e\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\x0cupper_row_id\x18\x02\x20\ - \x01(\tH\0R\nupperRowIdB\x15\n\x13one_of_upper_row_id\"d\n\x11QueryField\ - Payload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfie\ - ld_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\ - Y\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ - \x06gridId\x12&\n\x06blocks\x18\x02\x20\x03(\x0b2\x0e.GridBlockMetaR\x06\ - blocksb\x06proto3\ + erR\x0bfieldOrders\x122\n\x0cblock_orders\x18\x03\x20\x03(\x0b2\x0f.Grid\ + BlockOrderR\x0bblockOrders\"\xb8\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\ + \x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\ + \n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\ + \x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\ + \x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\ + \x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\"'\n\nFieldOrder\x12\ + \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"-\n\rRepeatedField\ + \x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12Re\ + peatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\ + \x05items\"<\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05ro\ + wId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\"3\n\x10Repeate\ + dRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05items\ + \"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12@\n\x10\ + cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\rcell\ + ByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\n\x12\ + CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\ + \x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\x0bRep\ + eatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05items\"5\n\ + \x11RepeatedGridBlock\x12\x20\n\x05items\x18\x01\x20\x03(\x0b2\n.GridBlo\ + ckR\x05items\"+\n\x0eGridBlockOrder\x12\x19\n\x08block_id\x18\x01\x20\ + \x01(\tR\x07blockId\"?\n\tGridBlock\x12\x19\n\x08block_id\x18\x01\x20\ + \x01(\tR\x07blockId\x12\x17\n\x07row_ids\x18\x02\x20\x03(\tR\x06rowIds\"\ + ;\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\ + \n\x07content\x18\x02\x20\x01(\tR\x07content\"+\n\x0cRepeatedCell\x12\ + \x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateG\ + ridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06Grid\ + Id\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\ + \x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayloa\ + d\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_ro\ + w_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\"d\ + \n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06grid\ + Id\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\"\\\n\x0fQueryRowPayload\x12\x17\n\ + \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\ + \x20\x01(\tR\x07blockId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\ + b\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/model/meta.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs index 0dcde28a6b..2e27686c00 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs @@ -28,7 +28,7 @@ pub struct GridMeta { // message fields pub grid_id: ::std::string::String, pub fields: ::protobuf::RepeatedField, - pub blocks: ::protobuf::RepeatedField, + pub block_metas: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -96,29 +96,29 @@ impl GridMeta { ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new()) } - // repeated .GridBlockMeta blocks = 3; + // repeated .GridBlockMeta block_metas = 3; - pub fn get_blocks(&self) -> &[GridBlockMeta] { - &self.blocks + pub fn get_block_metas(&self) -> &[GridBlockMeta] { + &self.block_metas } - pub fn clear_blocks(&mut self) { - self.blocks.clear(); + pub fn clear_block_metas(&mut self) { + self.block_metas.clear(); } // Param is passed by value, moved - pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField) { - self.blocks = v; + pub fn set_block_metas(&mut self, v: ::protobuf::RepeatedField) { + self.block_metas = v; } // Mutable pointer to the field. - pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.blocks + pub fn mut_block_metas(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.block_metas } // Take field - pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new()) + pub fn take_block_metas(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.block_metas, ::protobuf::RepeatedField::new()) } } @@ -129,7 +129,7 @@ impl ::protobuf::Message for GridMeta { return false; } }; - for v in &self.blocks { + for v in &self.block_metas { if !v.is_initialized() { return false; } @@ -148,7 +148,7 @@ impl ::protobuf::Message for GridMeta { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.fields)?; }, 3 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.block_metas)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -169,7 +169,7 @@ impl ::protobuf::Message for GridMeta { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; - for value in &self.blocks { + for value in &self.block_metas { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; @@ -187,7 +187,7 @@ impl ::protobuf::Message for GridMeta { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; }; - for v in &self.blocks { + for v in &self.block_metas { os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -241,9 +241,9 @@ impl ::protobuf::Message for GridMeta { |m: &mut GridMeta| { &mut m.fields }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "blocks", - |m: &GridMeta| { &m.blocks }, - |m: &mut GridMeta| { &mut m.blocks }, + "block_metas", + |m: &GridMeta| { &m.block_metas }, + |m: &mut GridMeta| { &mut m.block_metas }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "GridMeta", @@ -263,7 +263,7 @@ impl ::protobuf::Clear for GridMeta { fn clear(&mut self) { self.grid_id.clear(); self.fields.clear(); - self.blocks.clear(); + self.block_metas.clear(); self.unknown_fields.clear(); } } @@ -510,7 +510,7 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockMeta { } #[derive(PartialEq,Clone,Default)] -pub struct GridBlockMetaData { +pub struct GridBlockMetaSerde { // message fields pub block_id: ::std::string::String, pub row_metas: ::protobuf::RepeatedField, @@ -519,14 +519,14 @@ pub struct GridBlockMetaData { pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a GridBlockMetaData { - fn default() -> &'a GridBlockMetaData { - ::default_instance() +impl<'a> ::std::default::Default for &'a GridBlockMetaSerde { + fn default() -> &'a GridBlockMetaSerde { + ::default_instance() } } -impl GridBlockMetaData { - pub fn new() -> GridBlockMetaData { +impl GridBlockMetaSerde { + pub fn new() -> GridBlockMetaSerde { ::std::default::Default::default() } @@ -582,7 +582,7 @@ impl GridBlockMetaData { } } -impl ::protobuf::Message for GridBlockMetaData { +impl ::protobuf::Message for GridBlockMetaSerde { fn is_initialized(&self) -> bool { for v in &self.row_metas { if !v.is_initialized() { @@ -665,8 +665,8 @@ impl ::protobuf::Message for GridBlockMetaData { Self::descriptor_static() } - fn new() -> GridBlockMetaData { - GridBlockMetaData::new() + fn new() -> GridBlockMetaSerde { + GridBlockMetaSerde::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -675,29 +675,29 @@ impl ::protobuf::Message for GridBlockMetaData { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "block_id", - |m: &GridBlockMetaData| { &m.block_id }, - |m: &mut GridBlockMetaData| { &mut m.block_id }, + |m: &GridBlockMetaSerde| { &m.block_id }, + |m: &mut GridBlockMetaSerde| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "row_metas", - |m: &GridBlockMetaData| { &m.row_metas }, - |m: &mut GridBlockMetaData| { &mut m.row_metas }, + |m: &GridBlockMetaSerde| { &m.row_metas }, + |m: &mut GridBlockMetaSerde| { &mut m.row_metas }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GridBlockMetaData", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridBlockMetaSerde", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static GridBlockMetaData { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GridBlockMetaData::new) + fn default_instance() -> &'static GridBlockMetaSerde { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridBlockMetaSerde::new) } } -impl ::protobuf::Clear for GridBlockMetaData { +impl ::protobuf::Clear for GridBlockMetaSerde { fn clear(&mut self) { self.block_id.clear(); self.row_metas.clear(); @@ -705,13 +705,13 @@ impl ::protobuf::Clear for GridBlockMetaData { } } -impl ::std::fmt::Debug for GridBlockMetaData { +impl ::std::fmt::Debug for GridBlockMetaSerde { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for GridBlockMetaData { +impl ::protobuf::reflect::ProtobufValue for GridBlockMetaSerde { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -3119,8 +3119,8 @@ impl ::protobuf::reflect::ProtobufValue for CellMetaChangeset { pub struct BuildGridContext { // message fields pub field_metas: ::protobuf::RepeatedField, - pub grid_block: ::protobuf::SingularPtrField, - pub grid_block_meta_data: ::protobuf::SingularPtrField, + pub block_metas: ::protobuf::SingularPtrField, + pub block_meta_data: ::protobuf::SingularPtrField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -3162,70 +3162,70 @@ impl BuildGridContext { ::std::mem::replace(&mut self.field_metas, ::protobuf::RepeatedField::new()) } - // .GridBlockMeta grid_block = 2; + // .GridBlockMeta block_metas = 2; - pub fn get_grid_block(&self) -> &GridBlockMeta { - self.grid_block.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_block_metas(&self) -> &GridBlockMeta { + self.block_metas.as_ref().unwrap_or_else(|| ::default_instance()) } - pub fn clear_grid_block(&mut self) { - self.grid_block.clear(); + pub fn clear_block_metas(&mut self) { + self.block_metas.clear(); } - pub fn has_grid_block(&self) -> bool { - self.grid_block.is_some() + pub fn has_block_metas(&self) -> bool { + self.block_metas.is_some() } // Param is passed by value, moved - pub fn set_grid_block(&mut self, v: GridBlockMeta) { - self.grid_block = ::protobuf::SingularPtrField::some(v); + pub fn set_block_metas(&mut self, v: GridBlockMeta) { + self.block_metas = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_block(&mut self) -> &mut GridBlockMeta { - if self.grid_block.is_none() { - self.grid_block.set_default(); + pub fn mut_block_metas(&mut self) -> &mut GridBlockMeta { + if self.block_metas.is_none() { + self.block_metas.set_default(); } - self.grid_block.as_mut().unwrap() + self.block_metas.as_mut().unwrap() } // Take field - pub fn take_grid_block(&mut self) -> GridBlockMeta { - self.grid_block.take().unwrap_or_else(|| GridBlockMeta::new()) + pub fn take_block_metas(&mut self) -> GridBlockMeta { + self.block_metas.take().unwrap_or_else(|| GridBlockMeta::new()) } - // .GridBlockMetaData grid_block_meta_data = 3; + // .GridBlockMetaSerde block_meta_data = 3; - pub fn get_grid_block_meta_data(&self) -> &GridBlockMetaData { - self.grid_block_meta_data.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_block_meta_data(&self) -> &GridBlockMetaSerde { + self.block_meta_data.as_ref().unwrap_or_else(|| ::default_instance()) } - pub fn clear_grid_block_meta_data(&mut self) { - self.grid_block_meta_data.clear(); + pub fn clear_block_meta_data(&mut self) { + self.block_meta_data.clear(); } - pub fn has_grid_block_meta_data(&self) -> bool { - self.grid_block_meta_data.is_some() + pub fn has_block_meta_data(&self) -> bool { + self.block_meta_data.is_some() } // Param is passed by value, moved - pub fn set_grid_block_meta_data(&mut self, v: GridBlockMetaData) { - self.grid_block_meta_data = ::protobuf::SingularPtrField::some(v); + pub fn set_block_meta_data(&mut self, v: GridBlockMetaSerde) { + self.block_meta_data = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_block_meta_data(&mut self) -> &mut GridBlockMetaData { - if self.grid_block_meta_data.is_none() { - self.grid_block_meta_data.set_default(); + pub fn mut_block_meta_data(&mut self) -> &mut GridBlockMetaSerde { + if self.block_meta_data.is_none() { + self.block_meta_data.set_default(); } - self.grid_block_meta_data.as_mut().unwrap() + self.block_meta_data.as_mut().unwrap() } // Take field - pub fn take_grid_block_meta_data(&mut self) -> GridBlockMetaData { - self.grid_block_meta_data.take().unwrap_or_else(|| GridBlockMetaData::new()) + pub fn take_block_meta_data(&mut self) -> GridBlockMetaSerde { + self.block_meta_data.take().unwrap_or_else(|| GridBlockMetaSerde::new()) } } @@ -3236,12 +3236,12 @@ impl ::protobuf::Message for BuildGridContext { return false; } }; - for v in &self.grid_block { + for v in &self.block_metas { if !v.is_initialized() { return false; } }; - for v in &self.grid_block_meta_data { + for v in &self.block_meta_data { if !v.is_initialized() { return false; } @@ -3257,10 +3257,10 @@ impl ::protobuf::Message for BuildGridContext { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.field_metas)?; }, 2 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block)?; + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.block_metas)?; }, 3 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block_meta_data)?; + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.block_meta_data)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -3278,11 +3278,11 @@ impl ::protobuf::Message for BuildGridContext { let len = value.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; - if let Some(ref v) = self.grid_block.as_ref() { + if let Some(ref v) = self.block_metas.as_ref() { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } - if let Some(ref v) = self.grid_block_meta_data.as_ref() { + if let Some(ref v) = self.block_meta_data.as_ref() { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } @@ -3297,12 +3297,12 @@ impl ::protobuf::Message for BuildGridContext { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; }; - if let Some(ref v) = self.grid_block.as_ref() { + if let Some(ref v) = self.block_metas.as_ref() { os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; } - if let Some(ref v) = self.grid_block_meta_data.as_ref() { + if let Some(ref v) = self.block_meta_data.as_ref() { os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -3351,14 +3351,14 @@ impl ::protobuf::Message for BuildGridContext { |m: &mut BuildGridContext| { &mut m.field_metas }, )); fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "grid_block", - |m: &BuildGridContext| { &m.grid_block }, - |m: &mut BuildGridContext| { &mut m.grid_block }, + "block_metas", + |m: &BuildGridContext| { &m.block_metas }, + |m: &mut BuildGridContext| { &mut m.block_metas }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "grid_block_meta_data", - |m: &BuildGridContext| { &m.grid_block_meta_data }, - |m: &mut BuildGridContext| { &mut m.grid_block_meta_data }, + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "block_meta_data", + |m: &BuildGridContext| { &m.block_meta_data }, + |m: &mut BuildGridContext| { &mut m.block_meta_data }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "BuildGridContext", @@ -3377,8 +3377,8 @@ impl ::protobuf::Message for BuildGridContext { impl ::protobuf::Clear for BuildGridContext { fn clear(&mut self) { self.field_metas.clear(); - self.grid_block.clear(); - self.grid_block_meta_data.clear(); + self.block_metas.clear(); + self.block_meta_data.clear(); self.unknown_fields.clear(); } } @@ -3458,22 +3458,22 @@ impl ::protobuf::reflect::ProtobufValue for FieldType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\nmeta.proto\"o\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \n\nmeta.proto\"x\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ \x06gridId\x12\"\n\x06fields\x18\x02\x20\x03(\x0b2\n.FieldMetaR\x06field\ - s\x12&\n\x06blocks\x18\x03\x20\x03(\x0b2\x0e.GridBlockMetaR\x06blocks\"o\ - \n\rGridBlockMeta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\ - \x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\ - \n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"U\n\x11GridBlockMetaDat\ - a\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_metas\ - \x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xdf\x01\n\tFieldMeta\ - \x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\ - \x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nf\ - ield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06fro\ - zen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\ - \x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\ - \x12!\n\x0ctype_options\x18\x08\x20\x01(\tR\x0btypeOptions\"\xfd\x02\n\ - \x0eFieldChangeset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\ - \x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\ + s\x12/\n\x0bblock_metas\x18\x03\x20\x03(\x0b2\x0e.GridBlockMetaR\nblockM\ + etas\"o\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07bl\ + ockId\x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\ + \x1b\n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"V\n\x12GridBlockMet\ + aSerde\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_\ + metas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xdf\x01\n\tFieldM\ + eta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\ + \x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\ + \n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\ + \x06frozen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\ + \x20\x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05w\ + idth\x12!\n\x0ctype_options\x18\x08\x20\x01(\tR\x0btypeOptions\"\xfd\x02\ + \n\x0eFieldChangeset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldI\ + d\x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\ \x03\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x04\x20\x01(\x0e2\n\ .FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x05\x20\x01(\x08H\ \x03R\x06frozen\x12\x20\n\nvisibility\x18\x06\x20\x01(\x08H\x04R\nvisibi\ @@ -3501,14 +3501,13 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x11CellMetaChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ \x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\ \x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\ - \x04dataB\r\n\x0bone_of_data\"\xb3\x01\n\x10BuildGridContext\x12+\n\x0bf\ - ield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12-\n\ngrid_b\ - lock\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\tgridBlock\x12C\n\x14grid_\ - block_meta_data\x18\x03\x20\x01(\x0b2\x12.GridBlockMetaDataR\x11gridBloc\ - kMetaData*d\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\x08Checkbox\x10\x05b\x06prot\ - o3\ + \x04dataB\r\n\x0bone_of_data\"\xad\x01\n\x10BuildGridContext\x12+\n\x0bf\ + ield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12/\n\x0bbloc\ + k_metas\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\nblockMetas\x12;\n\x0fb\ + lock_meta_data\x18\x03\x20\x01(\x0b2\x13.GridBlockMetaSerdeR\rblockMetaD\ + ata*d\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\x08Checkbox\x10\x05b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 31119b015d..2e85b13411 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 @@ -4,7 +4,7 @@ import "meta.proto"; message Grid { string id = 1; repeated FieldOrder field_orders = 2; - repeated GridBlockMeta blocks = 3; + repeated GridBlockOrder block_orders = 3; } message Field { string id = 1; @@ -36,12 +36,18 @@ message Row { map cell_by_field_id = 2; int32 height = 3; } +message RepeatedRow { + repeated Row items = 1; +} message RepeatedGridBlock { repeated GridBlock items = 1; } +message GridBlockOrder { + string block_id = 1; +} message GridBlock { string block_id = 1; - repeated Row rows = 2; + repeated string row_ids = 2; } message Cell { string field_id = 1; @@ -61,7 +67,7 @@ message GridBlockId { } message CreateRowPayload { string grid_id = 1; - oneof one_of_upper_row_id { string upper_row_id = 2; }; + oneof one_of_start_row_id { string start_row_id = 2; }; } message QueryFieldPayload { string grid_id = 1; @@ -69,5 +75,10 @@ message QueryFieldPayload { } message QueryGridBlocksPayload { string grid_id = 1; - repeated GridBlockMeta blocks = 2; + repeated GridBlockOrder block_orders = 2; +} +message QueryRowPayload { + string grid_id = 1; + string block_id = 2; + string row_id = 3; } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto index aa23f08a02..24e1d22696 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto @@ -3,14 +3,14 @@ syntax = "proto3"; message GridMeta { string grid_id = 1; repeated FieldMeta fields = 2; - repeated GridBlockMeta blocks = 3; + repeated GridBlockMeta block_metas = 3; } message GridBlockMeta { string block_id = 1; int32 start_row_index = 2; int32 row_count = 3; } -message GridBlockMetaData { +message GridBlockMetaSerde { string block_id = 1; repeated RowMeta row_metas = 2; } @@ -63,8 +63,8 @@ message CellMetaChangeset { } message BuildGridContext { repeated FieldMeta field_metas = 1; - GridBlockMeta grid_block = 2; - GridBlockMetaData grid_block_meta_data = 3; + GridBlockMeta block_metas = 2; + GridBlockMetaSerde block_meta_data = 3; } enum FieldType { RichText = 0; diff --git a/shared-lib/flowy-grid-data-model/tests/serde_test.rs b/shared-lib/flowy-grid-data-model/tests/serde_test.rs index 0847950b98..15367cc5ac 100644 --- a/shared-lib/flowy-grid-data-model/tests/serde_test.rs +++ b/shared-lib/flowy-grid-data-model/tests/serde_test.rs @@ -7,7 +7,7 @@ fn grid_serde_test() { let grid = GridMeta { grid_id, fields, - blocks: vec![], + block_metas: vec![], }; let grid_1_json = serde_json::to_string(&grid).unwrap(); @@ -24,7 +24,7 @@ fn grid_default_serde_test() { let grid = GridMeta { grid_id, fields: vec![], - blocks: vec![], + block_metas: vec![], }; let json = serde_json::to_string(&grid).unwrap(); From 318d7e645640e4fa75cd5bbc9292757867bf9da6 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 18 Mar 2022 21:04:01 +0800 Subject: [PATCH 28/28] chore: fix warnings --- .../application/grid/grid_block_service.dart | 9 +- .../application/grid/grid_service.dart | 3 + .../workspace/application/grid/row_bloc.dart | 32 +- .../application/grid/row_service.dart | 2 + .../presentation/plugins/grid/grid.dart | 2 +- .../src/widgets/content/cell_builder.dart | 1 - .../grid/src/widgets/content/grid_row.dart | 25 +- .../flowy-grid-data-model/grid.pb.dart | 63 +--- .../flowy-grid-data-model/grid.pbjson.dart | 17 +- frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- .../rust-lib/flowy-grid/src/event_handler.rs | 2 +- .../src/services/block_meta_editor.rs | 30 +- .../flowy-grid/src/services/grid_editor.rs | 30 +- .../src/services/row/row_builder.rs | 35 +- .../flowy-grid/src/services/row/row_loader.rs | 22 +- .../rust-lib/flowy-grid/src/services/util.rs | 33 -- .../flowy-grid/tests/grid/grid_test.rs | 16 +- .../rust-lib/flowy-grid/tests/grid/script.rs | 25 +- .../src/entities/grid.rs | 39 +-- .../src/entities/meta.rs | 2 - .../flowy-grid-data-model/src/parser/id.rs | 2 - .../src/protobuf/model/grid.rs | 310 ++++++------------ .../src/protobuf/proto/grid.proto | 6 +- 23 files changed, 253 insertions(+), 457 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart index 973f412e9e..3672a910f4 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_block_service.dart @@ -37,13 +37,14 @@ class GridBlockService { List rows() { List rows = []; - blockMap.forEach((_, gridBlock) { - rows.addAll(gridBlock.rowIds.map( - (rowId) => GridRowData( + blockMap.forEach((_, GridBlock gridBlock) { + rows.addAll(gridBlock.rowOrders.map( + (rowOrder) => GridRowData( gridId: gridId, fields: fields, blockId: gridBlock.blockId, - rowId: rowId, + rowId: rowOrder.rowId, + height: rowOrder.height.toDouble(), ), )); }); diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index 976860029e..506401706b 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -40,11 +40,14 @@ class GridRowData extends Equatable { final String rowId; final String blockId; final List fields; + final double height; + const GridRowData({ required this.gridId, required this.rowId, required this.blockId, required this.fields, + required this.height, }); @override diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart index 32525a1bb7..bf13c682d7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_bloc.dart @@ -1,4 +1,5 @@ import 'package:flowy_sdk/log.dart'; +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'; @@ -61,20 +62,29 @@ class RowBloc extends Bloc { final result = await rowService.getRow(); result.fold( (row) { - final cellDatas = rowService.rowData.fields.map((field) { - final cell = row.cellByFieldId[field.id]; - return GridCellData( - rowId: row.id, - gridId: rowService.rowData.gridId, - cell: cell, - field: field, - ); - }).toList(); - emit(state.copyWith(cellDatas: cellDatas, rowHeight: row.height.toDouble())); + emit(state.copyWith( + cellDatas: makeGridCellDatas(row), + rowHeight: row.height.toDouble(), + )); }, (e) => Log.error(e), ); } + + List makeGridCellDatas(Row row) { + return rowService.rowData.fields.map((field) { + final cell = row.cellByFieldId[field.id]; + final rowData = rowService.rowData; + + return GridCellData( + rowId: row.id, + gridId: rowData.gridId, + blockId: rowData.blockId, + cell: cell, + field: field, + ); + }).toList(); + } } @freezed @@ -97,7 +107,7 @@ abstract class RowState with _$RowState { factory RowState.initial(GridRowData data) => RowState( rowId: data.rowId, active: false, - rowHeight: 0, + rowHeight: data.height, cellDatas: [], ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart index 986442c47e..013ae3fb1c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row_service.dart @@ -31,12 +31,14 @@ class RowService { class GridCellData { final String gridId; final String rowId; + final String blockId; final Field field; final Cell? cell; GridCellData({ required this.rowId, required this.gridId, + required this.blockId, required this.field, required this.cell, }); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart index b73970508c..cf6b4c9032 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart @@ -28,7 +28,7 @@ class GridPluginBuilder implements PluginBuilder { class GridPluginConfig implements PluginConfig { @override - bool get creatable => true; + bool get creatable => false; } class GridPlugin extends Plugin { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index 2bb1782f13..187a81c1bc 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -1,4 +1,3 @@ -import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/row_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; import 'package:flutter/widgets.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index 45f5f89c38..f062202744 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -36,16 +36,21 @@ class _GridRowWidgetState extends State { cursor: SystemMouseCursors.click, onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()), onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()), - child: SizedBox( - height: _rowBloc.state.rowHeight, - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const LeadingRow(), - _buildCells(), - const TrailingRow(), - ], - ), + child: BlocBuilder( + buildWhen: (p, c) => p.rowHeight != c.rowHeight, + builder: (context, state) { + return SizedBox( + height: _rowBloc.state.rowHeight, + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const LeadingRow(), + _buildCells(), + const TrailingRow(), + ], + ), + ); + }, ), ), ), 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 b44a3e7814..bc713bbdb8 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 @@ -338,6 +338,7 @@ class RowOrder extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowOrder', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3) ..hasRequiredFields = false ; @@ -345,6 +346,7 @@ class RowOrder extends $pb.GeneratedMessage { factory RowOrder({ $core.String? rowId, $core.String? blockId, + $core.int? height, }) { final _result = create(); if (rowId != null) { @@ -353,6 +355,9 @@ class RowOrder extends $pb.GeneratedMessage { if (blockId != null) { _result.blockId = blockId; } + if (height != null) { + _result.height = height; + } return _result; } factory RowOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -393,47 +398,15 @@ class RowOrder extends $pb.GeneratedMessage { $core.bool hasBlockId() => $_has(1); @$pb.TagNumber(2) void clearBlockId() => clearField(2); -} -class RepeatedRowOrder extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedRowOrder', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: RowOrder.create) - ..hasRequiredFields = false - ; - - RepeatedRowOrder._() : super(); - factory RepeatedRowOrder({ - $core.Iterable? items, - }) { - final _result = create(); - if (items != null) { - _result.items.addAll(items); - } - return _result; - } - factory RepeatedRowOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RepeatedRowOrder.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RepeatedRowOrder clone() => RepeatedRowOrder()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RepeatedRowOrder copyWith(void Function(RepeatedRowOrder) updates) => super.copyWith((message) => updates(message as RepeatedRowOrder)) as RepeatedRowOrder; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RepeatedRowOrder create() => RepeatedRowOrder._(); - RepeatedRowOrder createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RepeatedRowOrder getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RepeatedRowOrder? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get items => $_getList(0); + @$pb.TagNumber(3) + $core.int get height => $_getIZ(2); + @$pb.TagNumber(3) + set height($core.int v) { $_setSignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasHeight() => $_has(2); + @$pb.TagNumber(3) + void clearHeight() => clearField(3); } class Row extends $pb.GeneratedMessage { @@ -637,21 +610,21 @@ class GridBlockOrder extends $pb.GeneratedMessage { class GridBlock extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') - ..pPS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowIds') + ..pc(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', $pb.PbFieldType.PM, subBuilder: RowOrder.create) ..hasRequiredFields = false ; GridBlock._() : super(); factory GridBlock({ $core.String? blockId, - $core.Iterable<$core.String>? rowIds, + $core.Iterable? rowOrders, }) { final _result = create(); if (blockId != null) { _result.blockId = blockId; } - if (rowIds != null) { - _result.rowIds.addAll(rowIds); + if (rowOrders != null) { + _result.rowOrders.addAll(rowOrders); } return _result; } @@ -686,7 +659,7 @@ class GridBlock extends $pb.GeneratedMessage { void clearBlockId() => clearField(1); @$pb.TagNumber(2) - $core.List<$core.String> get rowIds => $_getList(1); + $core.List get rowOrders => $_getList(1); } class Cell 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 c4d79ccb0b..5e24c82178 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 @@ -72,21 +72,12 @@ const RowOrder$json = const { '2': const [ const {'1': 'row_id', '3': 1, '4': 1, '5': 9, '10': 'rowId'}, const {'1': 'block_id', '3': 2, '4': 1, '5': 9, '10': 'blockId'}, + const {'1': 'height', '3': 3, '4': 1, '5': 5, '10': 'height'}, ], }; /// Descriptor for `RowOrder`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rowOrderDescriptor = $convert.base64Decode('CghSb3dPcmRlchIVCgZyb3dfaWQYASABKAlSBXJvd0lkEhkKCGJsb2NrX2lkGAIgASgJUgdibG9ja0lk'); -@$core.Deprecated('Use repeatedRowOrderDescriptor instead') -const RepeatedRowOrder$json = const { - '1': 'RepeatedRowOrder', - '2': const [ - const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.RowOrder', '10': 'items'}, - ], -}; - -/// Descriptor for `RepeatedRowOrder`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List repeatedRowOrderDescriptor = $convert.base64Decode('ChBSZXBlYXRlZFJvd09yZGVyEh8KBWl0ZW1zGAEgAygLMgkuUm93T3JkZXJSBWl0ZW1z'); +final $typed_data.Uint8List rowOrderDescriptor = $convert.base64Decode('CghSb3dPcmRlchIVCgZyb3dfaWQYASABKAlSBXJvd0lkEhkKCGJsb2NrX2lkGAIgASgJUgdibG9ja0lkEhYKBmhlaWdodBgDIAEoBVIGaGVpZ2h0'); @$core.Deprecated('Use rowDescriptor instead') const Row$json = const { '1': 'Row', @@ -145,12 +136,12 @@ const GridBlock$json = const { '1': 'GridBlock', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'row_ids', '3': 2, '4': 3, '5': 9, '10': 'rowIds'}, + const {'1': 'row_orders', '3': 2, '4': 3, '5': 11, '6': '.RowOrder', '10': 'rowOrders'}, ], }; /// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSFwoHcm93X2lkcxgCIAMoCVIGcm93SWRz'); +final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSKAoKcm93X29yZGVycxgCIAMoCzIJLlJvd09yZGVyUglyb3dPcmRlcnM='); @$core.Deprecated('Use cellDescriptor instead') const Cell$json = const { '1': 'Cell', diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 046fd85668..96755db623 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -7,8 +7,8 @@ edition = "2018" [lib] name = "dart_ffi" # this value will change depending on the target os -# default cdylib -crate-type = ["cdylib"] +# default staticlib +crate-type = ["staticlib"] [dependencies] diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index d6022769fb..73aed6da43 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -2,7 +2,7 @@ use crate::manager::GridManager; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ CellMetaChangeset, CreateRowPayload, Field, Grid, GridId, QueryFieldPayload, QueryGridBlocksPayload, - QueryRowPayload, RepeatedField, RepeatedGridBlock, RepeatedRow, Row, + QueryRowPayload, RepeatedField, RepeatedGridBlock, Row, }; use flowy_grid_data_model::parser::{CreateRowParams, QueryFieldParams, QueryGridBlocksParams, QueryRowParams}; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; 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 f8ba93b906..650b537221 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 @@ -9,8 +9,7 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, RepeatedCell, RepeatedRowOrder, RowMeta, - RowMetaChangeset, RowOrder, + FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, RepeatedCell, RowMeta, RowMetaChangeset, RowOrder, }; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_sync::{ @@ -92,16 +91,7 @@ impl GridBlockMetaEditorManager { Ok(changesets) } - pub(crate) async fn delete_rows(&self, row_ids: Vec) -> FlowyResult> { - let row_orders = row_ids - .into_iter() - .flat_map(|row_id| { - self.block_id_by_row_id.get(&row_id).map(|block_id| RowOrder { - row_id, - block_id: block_id.clone(), - }) - }) - .collect::>(); + pub(crate) async fn delete_rows(&self, row_orders: Vec) -> FlowyResult> { let mut changesets = vec![]; let row_ids_per_blocks = make_row_ids_per_block(&row_orders); for row_ids_per_block in row_ids_per_blocks { @@ -163,7 +153,7 @@ impl GridBlockMetaEditorManager { pub(crate) async fn get_block_meta_data(&self, block_ids: &[String]) -> FlowyResult> { let mut snapshots = vec![]; for block_id in block_ids { - let editor = self.get_editor(&block_id).await?; + let editor = self.get_editor(block_id).await?; let row_metas = editor.get_row_metas(None).await?; row_metas.iter().for_each(|row_meta| { self.block_id_by_row_id @@ -177,16 +167,6 @@ impl GridBlockMetaEditorManager { Ok(snapshots) } - pub(crate) async fn get_row_orders(&self, grid_block_ids: Vec) -> FlowyResult> { - let mut row_orders = vec![]; - for grid_block_id in grid_block_ids { - let editor = self.get_editor(&grid_block_id).await?; - let new_row_order = editor.get_row_orders().await?; - row_orders.extend(new_row_order); - } - Ok(row_orders) - } - async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { match self.block_id_by_row_id.get(row_id) { None => { @@ -328,12 +308,12 @@ impl ClientGridBlockMetaEditor { Ok(row_metas) } - pub async fn get_row_orders(&self) -> FlowyResult> { + pub async fn get_row_orders(&self, row_ids: Option>) -> FlowyResult> { let row_orders = self .pad .read() .await - .get_rows(None)? + .get_rows(row_ids)? .iter() .map(RowOrder::from) .collect::>(); 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 8f4d82d992..d1276bb8ab 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -6,16 +6,15 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Cell, CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlockMeta, GridBlockMetaChangeset, - GridBlockOrder, RepeatedField, RepeatedFieldOrder, RepeatedGridBlock, RepeatedRow, RepeatedRowOrder, Row, RowMeta, - RowMetaChangeset, + CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlockMeta, GridBlockMetaChangeset, GridBlockOrder, + RepeatedField, RepeatedFieldOrder, RepeatedGridBlock, RepeatedRow, Row, RowMeta, RowMetaChangeset, RowOrder, }; use std::collections::HashMap; use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::services::row::{ - make_grid_block_from_block_metas, make_grid_blocks, make_row_ids_per_block, make_rows_from_row_metas, - row_meta_from_context, serialize_cell_data, GridBlockMetaData, RowMetaContext, RowMetaContextBuilder, + make_grid_block_from_block_metas, make_grid_blocks, make_row_meta_from_context, make_rows_from_row_metas, + serialize_cell_data, CreateRowMetaBuilder, CreateRowMetaPayload, GridBlockMetaData, }; use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; @@ -85,13 +84,14 @@ impl ClientGridEditor { Ok(()) } - pub async fn create_row(&self, start_row_id: Option) -> FlowyResult<()> { + pub async fn create_row(&self, start_row_id: Option) -> FlowyResult { let field_metas = self.pad.read().await.get_field_metas(None)?; let block_id = self.block_id().await?; // insert empty row below the row whose id is upper_row_id - let row_meta_ctx = RowMetaContextBuilder::new(&field_metas).build(); - let row_meta = row_meta_from_context(&block_id, row_meta_ctx); + let row_meta_ctx = CreateRowMetaBuilder::new(&field_metas).build(); + let row_meta = make_row_meta_from_context(&block_id, row_meta_ctx); + let row_order = RowOrder::from(&row_meta); // insert the row let row_count = self @@ -102,14 +102,16 @@ impl ClientGridEditor { // update block row count let changeset = GridBlockMetaChangeset::from_row_count(&block_id, row_count); let _ = self.update_block(changeset).await?; - Ok(()) + Ok(row_order) } - pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult<()> { + pub async fn insert_rows(&self, contexts: Vec) -> FlowyResult> { let block_id = self.block_id().await?; let mut rows_by_block_id: HashMap> = HashMap::new(); + let mut row_orders = vec![]; for ctx in contexts { - let row_meta = row_meta_from_context(&block_id, ctx); + let row_meta = make_row_meta_from_context(&block_id, ctx); + row_orders.push(RowOrder::from(&row_meta)); rows_by_block_id .entry(block_id.clone()) .or_insert_with(Vec::new) @@ -119,7 +121,7 @@ impl ClientGridEditor { for changeset in changesets { let _ = self.update_block(changeset).await?; } - Ok(()) + Ok(row_orders) } pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { @@ -188,8 +190,8 @@ impl ClientGridEditor { Ok(grid_blocks) } - pub async fn delete_rows(&self, row_ids: Vec) -> FlowyResult<()> { - let changesets = self.block_meta_manager.delete_rows(row_ids).await?; + pub async fn delete_rows(&self, row_orders: Vec) -> FlowyResult<()> { + let changesets = self.block_meta_manager.delete_rows(row_orders).await?; for changeset in changesets { let _ = self.update_block(changeset).await?; } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index ce8ac6e53d..cbaae78fed 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -3,26 +3,29 @@ use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT}; use std::collections::HashMap; -pub struct RowMetaContextBuilder<'a> { +pub struct CreateRowMetaBuilder<'a> { field_meta_map: HashMap<&'a String, &'a FieldMeta>, - ctx: RowMetaContext, + payload: CreateRowMetaPayload, } -impl<'a> RowMetaContextBuilder<'a> { +impl<'a> CreateRowMetaBuilder<'a> { pub fn new(fields: &'a [FieldMeta]) -> Self { let field_meta_map = fields .iter() .map(|field| (&field.id, field)) .collect::>(); - let ctx = RowMetaContext { + let payload = CreateRowMetaPayload { row_id: uuid::Uuid::new_v4().to_string(), cell_by_field_id: Default::default(), height: DEFAULT_ROW_HEIGHT, visibility: true, }; - Self { field_meta_map, ctx } + Self { + field_meta_map, + payload, + } } pub fn add_cell(&mut self, field_id: &str, data: String) -> FlowyResult<()> { @@ -34,7 +37,7 @@ impl<'a> RowMetaContextBuilder<'a> { Some(field_meta) => { let data = serialize_cell_data(&data, field_meta)?; let cell = CellMeta::new(field_id, data); - self.ctx.cell_by_field_id.insert(field_id.to_owned(), cell); + self.payload.cell_by_field_id.insert(field_id.to_owned(), cell); Ok(()) } } @@ -42,32 +45,32 @@ impl<'a> RowMetaContextBuilder<'a> { #[allow(dead_code)] pub fn height(mut self, height: i32) -> Self { - self.ctx.height = height; + self.payload.height = height; self } #[allow(dead_code)] pub fn visibility(mut self, visibility: bool) -> Self { - self.ctx.visibility = visibility; + self.payload.visibility = visibility; self } - pub fn build(self) -> RowMetaContext { - self.ctx + pub fn build(self) -> CreateRowMetaPayload { + self.payload } } -pub fn row_meta_from_context(block_id: &str, ctx: RowMetaContext) -> RowMeta { +pub fn make_row_meta_from_context(block_id: &str, payload: CreateRowMetaPayload) -> RowMeta { RowMeta { - id: ctx.row_id, + id: payload.row_id, block_id: block_id.to_owned(), - cell_by_field_id: ctx.cell_by_field_id, - height: ctx.height, - visibility: ctx.visibility, + cell_by_field_id: payload.cell_by_field_id, + height: payload.height, + visibility: payload.visibility, } } -pub struct RowMetaContext { +pub struct CreateRowMetaPayload { pub row_id: String, pub cell_by_field_id: HashMap, pub height: i32, 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 8d1e683a6e..bf2f62c776 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 @@ -1,7 +1,7 @@ use crate::services::row::deserialize_cell_data; use flowy_error::FlowyResult; use flowy_grid_data_model::entities::{ - Cell, CellMeta, FieldMeta, GridBlock, RepeatedGridBlock, RepeatedRowOrder, Row, RowMeta, RowOrder, + Cell, CellMeta, FieldMeta, GridBlock, RepeatedGridBlock, Row, RowMeta, RowOrder, }; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; @@ -32,8 +32,8 @@ pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec) -> Ok(block_meta_snapshots .into_iter() .map(|row_metas_per_block| { - let row_ids = make_row_ids_from_row_metas(&row_metas_per_block.row_metas); + let row_orders = make_row_orders_from_row_metas(&row_metas_per_block.row_metas); GridBlock { block_id: row_metas_per_block.block_id, - row_ids, + row_orders, } }) .collect::>() @@ -73,11 +73,11 @@ pub fn make_cell( } } -pub(crate) fn make_row_ids_from_row_metas(row_metas: &Vec>) -> Vec { - row_metas.iter().map(|row_meta| row_meta.id.clone()).collect::>() +pub(crate) fn make_row_orders_from_row_metas(row_metas: &[Arc]) -> Vec { + row_metas.iter().map(RowOrder::from).collect::>() } -pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &Vec>) -> Vec { +pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &[Arc]) -> Vec { let field_meta_map = fields .iter() .map(|field_meta| (&field_meta.id, field_meta)) @@ -98,7 +98,7 @@ pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &Vec>() + row_metas.iter().map(make_row).collect::>() } pub(crate) fn make_grid_block_from_block_metas( @@ -115,8 +115,8 @@ pub(crate) fn make_grid_block_from_block_metas( match block_meta_data_map.get(&block_id) { None => {} Some(row_metas) => { - let row_ids = make_row_ids_from_row_metas(row_metas); - grid_blocks.push(GridBlock::new(block_id, row_ids)); + let row_orders = make_row_orders_from_row_metas(row_metas); + grid_blocks.push(GridBlock::new(block_id, row_orders)); } } } diff --git a/frontend/rust-lib/flowy-grid/src/services/util.rs b/frontend/rust-lib/flowy-grid/src/services/util.rs index b5c838fa12..7370a1b19c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/util.rs +++ b/frontend/rust-lib/flowy-grid/src/services/util.rs @@ -1,36 +1,3 @@ -// -// #[allow(dead_code)] -// pub fn string_to_money(money_str: &str) -> Option> { -// let mut process_money_str = String::from(money_str); -// let default_currency = MoneySymbol::from_symbol_str("CNY").currency(); -// -// if process_money_str.is_empty() { -// return None; -// } -// -// return if process_money_str.chars().all(char::is_numeric) { -// match Money::from_str(&process_money_str, default_currency) { -// Ok(money) => Some(money), -// Err(_) => None, -// } -// } else { -// let symbol = process_money_str.chars().next().unwrap().to_string(); -// let mut currency = default_currency; -// -// for key in CURRENCIES_BY_SYMBOL.keys() { -// if symbol.eq(key) { -// currency = CURRENCIES_BY_SYMBOL.get(key).unwrap(); -// crop_letters(&mut process_money_str, 1); -// } -// } -// -// match Money::from_str(&process_money_str, currency) { -// Ok(money) => Some(money), -// Err(_) => None, -// } -// }; -// } - pub fn uuid() -> String { uuid::Uuid::new_v4().to_string() } 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 dcc077be35..abc00d5fb2 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::cell::*; -use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, RowMetaContextBuilder}; +use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, CreateRowMetaBuilder}; use flowy_grid_data_model::entities::{ CellMetaChangeset, FieldChangeset, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset, }; @@ -179,7 +179,7 @@ async fn grid_create_row() { #[tokio::test] async fn grid_create_row2() { let mut test = GridEditorTest::new().await; - let create_row_context = RowMetaContextBuilder::new(&test.field_metas).build(); + let create_row_context = CreateRowMetaBuilder::new(&test.field_metas).build(); let scripts = vec![ AssertRowCount(3), CreateRow { @@ -193,7 +193,7 @@ async fn grid_create_row2() { #[tokio::test] async fn grid_update_row() { let mut test = GridEditorTest::new().await; - let context = RowMetaContextBuilder::new(&test.field_metas).build(); + let context = CreateRowMetaBuilder::new(&test.field_metas).build(); let changeset = RowMetaChangeset { row_id: context.row_id.clone(), height: None, @@ -216,8 +216,8 @@ async fn grid_update_row() { #[tokio::test] async fn grid_delete_row() { let mut test = GridEditorTest::new().await; - let context_1 = RowMetaContextBuilder::new(&test.field_metas).build(); - let context_2 = RowMetaContextBuilder::new(&test.field_metas).build(); + let context_1 = CreateRowMetaBuilder::new(&test.field_metas).build(); + let context_2 = CreateRowMetaBuilder::new(&test.field_metas).build(); let row_ids = vec![context_1.row_id.clone(), context_2.row_id.clone()]; let scripts = vec![ AssertRowCount(3), @@ -242,7 +242,7 @@ async fn grid_delete_row() { #[tokio::test] async fn grid_row_add_cells_test() { let mut test = GridEditorTest::new().await; - let mut builder = RowMetaContextBuilder::new(&test.field_metas); + let mut builder = CreateRowMetaBuilder::new(&test.field_metas); for field in &test.field_metas { match field.field_type { FieldType::RichText => { @@ -288,7 +288,7 @@ async fn grid_row_add_cells_test() { #[tokio::test] async fn grid_row_add_selection_cell_test() { let mut test = GridEditorTest::new().await; - let mut builder = RowMetaContextBuilder::new(&test.field_metas); + let mut builder = CreateRowMetaBuilder::new(&test.field_metas); let uuid = uuid::Uuid::new_v4().to_string(); let mut single_select_field_id = "".to_string(); let mut multi_select_field_id = "".to_string(); @@ -343,7 +343,7 @@ async fn grid_row_add_selection_cell_test() { #[tokio::test] async fn grid_row_add_date_cell_test() { let mut test = GridEditorTest::new().await; - let mut builder = RowMetaContextBuilder::new(&test.field_metas); + let mut builder = CreateRowMetaBuilder::new(&test.field_metas); let mut date_field = None; let timestamp = 1647390674; for field in &test.field_metas { diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 571ca1ab95..eba36d8bbd 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,13 +1,14 @@ use bytes::Bytes; use flowy_collaboration::client_grid::GridBuilder; +use std::collections::HashMap; use flowy_grid::services::cell::*; use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; -use flowy_grid::services::row::RowMetaContext; +use flowy_grid::services::row::CreateRowMetaPayload; use flowy_grid_data_model::entities::{ BuildGridContext, CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlockMeta, GridBlockMetaChangeset, - RowMeta, RowMetaChangeset, + RowMeta, RowMetaChangeset, RowOrder, }; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_test::helper::ViewTest; @@ -50,7 +51,7 @@ pub enum EditorScript { }, CreateEmptyRow, CreateRow { - context: RowMetaContext, + context: CreateRowMetaPayload, }, UpdateRow { changeset: RowMetaChangeset, @@ -78,6 +79,8 @@ pub struct GridEditorTest { pub grid_blocks: Vec, pub row_metas: Vec>, pub field_count: usize, + + pub row_order_by_row_id: HashMap, } impl GridEditorTest { @@ -101,6 +104,7 @@ impl GridEditorTest { grid_blocks, row_metas, field_count: FieldType::COUNT, + row_order_by_row_id: HashMap::default(), } } @@ -172,18 +176,27 @@ impl GridEditorTest { assert_eq!(compared_block, block); } EditorScript::CreateEmptyRow => { - self.editor.create_row(None).await.unwrap(); + let row_order = self.editor.create_row(None).await.unwrap(); + self.row_order_by_row_id.insert(row_order.row_id.clone(), row_order); self.row_metas = self.get_row_metas().await; self.grid_blocks = self.editor.get_block_metas().await.unwrap(); } EditorScript::CreateRow { context } => { - self.editor.insert_rows(vec![context]).await.unwrap(); + let row_orders = self.editor.insert_rows(vec![context]).await.unwrap(); + for row_order in row_orders { + self.row_order_by_row_id.insert(row_order.row_id.clone(), row_order); + } self.row_metas = self.get_row_metas().await; self.grid_blocks = self.editor.get_block_metas().await.unwrap(); } EditorScript::UpdateRow { changeset: change } => self.editor.update_row(change).await.unwrap(), EditorScript::DeleteRow { row_ids } => { - self.editor.delete_rows(row_ids).await.unwrap(); + let row_orders = row_ids + .into_iter() + .map(|row_id| self.row_order_by_row_id.get(&row_id).unwrap().clone()) + .collect::>(); + + self.editor.delete_rows(row_orders).await.unwrap(); self.row_metas = self.get_row_metas().await; self.grid_blocks = self.editor.get_block_metas().await.unwrap(); } 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 48aa574298..c195a85c24 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,9 +1,6 @@ use crate::entities::{FieldMeta, FieldType, RowMeta}; use flowy_derive::ProtoBuf; use std::collections::HashMap; - -use crate::parser::NonEmptyId; -use flowy_error_code::ErrorCode; use std::sync::Arc; #[derive(Debug, Clone, Default, ProtoBuf)] @@ -114,6 +111,9 @@ pub struct RowOrder { #[pb(index = 2)] pub block_id: String, + + #[pb(index = 3)] + pub height: i32, } impl std::convert::From<&RowMeta> for RowOrder { @@ -121,6 +121,7 @@ impl std::convert::From<&RowMeta> for RowOrder { Self { row_id: row.id.clone(), block_id: row.block_id.clone(), + height: row.height, } } } @@ -130,35 +131,11 @@ impl std::convert::From<&Arc> for RowOrder { Self { row_id: row.id.clone(), block_id: row.block_id.clone(), + height: row.height, } } } -#[derive(Debug, Clone, Default, ProtoBuf)] -pub struct RepeatedRowOrder { - #[pb(index = 1)] - pub items: Vec, -} - -impl std::ops::Deref for RepeatedRowOrder { - type Target = Vec; - fn deref(&self) -> &Self::Target { - &self.items - } -} - -impl std::ops::DerefMut for RepeatedRowOrder { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.items - } -} - -impl std::convert::From> for RepeatedRowOrder { - fn from(items: Vec) -> Self { - Self { items } - } -} - #[derive(Debug, Default, ProtoBuf)] pub struct Row { #[pb(index = 1)] @@ -207,14 +184,14 @@ pub struct GridBlock { pub block_id: String, #[pb(index = 2)] - pub row_ids: Vec, + pub row_orders: Vec, } impl GridBlock { - pub fn new(block_id: &str, row_ids: Vec) -> Self { + pub fn new(block_id: &str, row_orders: Vec) -> Self { Self { block_id: block_id.to_owned(), - row_ids, + row_orders, } } } diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index c7c621d7ec..9ba374169c 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -1,8 +1,6 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; - -use crate::entities::GridBlockOrder; use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; pub const DEFAULT_ROW_HEIGHT: i32 = 36; diff --git a/shared-lib/flowy-grid-data-model/src/parser/id.rs b/shared-lib/flowy-grid-data-model/src/parser/id.rs index 0f35fbfef5..5dbe65cf04 100644 --- a/shared-lib/flowy-grid-data-model/src/parser/id.rs +++ b/shared-lib/flowy-grid-data-model/src/parser/id.rs @@ -1,5 +1,3 @@ -use flowy_error_code::ErrorCode; - #[derive(Debug)] pub struct NonEmptyId(pub String); 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 630e109891..fc538875c9 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 @@ -1155,6 +1155,7 @@ pub struct RowOrder { // message fields pub row_id: ::std::string::String, pub block_id: ::std::string::String, + pub height: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -1222,6 +1223,21 @@ impl RowOrder { pub fn take_block_id(&mut self) -> ::std::string::String { ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) } + + // int32 height = 3; + + + pub fn get_height(&self) -> i32 { + self.height + } + pub fn clear_height(&mut self) { + self.height = 0; + } + + // Param is passed by value, moved + pub fn set_height(&mut self, v: i32) { + self.height = v; + } } impl ::protobuf::Message for RowOrder { @@ -1239,6 +1255,13 @@ impl ::protobuf::Message for RowOrder { 2 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.height = tmp; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -1257,6 +1280,9 @@ impl ::protobuf::Message for RowOrder { if !self.block_id.is_empty() { my_size += ::protobuf::rt::string_size(2, &self.block_id); } + if self.height != 0 { + my_size += ::protobuf::rt::value_size(3, self.height, ::protobuf::wire_format::WireTypeVarint); + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -1269,6 +1295,9 @@ impl ::protobuf::Message for RowOrder { if !self.block_id.is_empty() { os.write_string(2, &self.block_id)?; } + if self.height != 0 { + os.write_int32(3, self.height)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -1317,6 +1346,11 @@ impl ::protobuf::Message for RowOrder { |m: &RowOrder| { &m.block_id }, |m: &mut RowOrder| { &mut m.block_id }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "height", + |m: &RowOrder| { &m.height }, + |m: &mut RowOrder| { &mut m.height }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "RowOrder", fields, @@ -1335,6 +1369,7 @@ impl ::protobuf::Clear for RowOrder { fn clear(&mut self) { self.row_id.clear(); self.block_id.clear(); + self.height = 0; self.unknown_fields.clear(); } } @@ -1351,172 +1386,6 @@ impl ::protobuf::reflect::ProtobufValue for RowOrder { } } -#[derive(PartialEq,Clone,Default)] -pub struct RepeatedRowOrder { - // message fields - pub items: ::protobuf::RepeatedField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a RepeatedRowOrder { - fn default() -> &'a RepeatedRowOrder { - ::default_instance() - } -} - -impl RepeatedRowOrder { - pub fn new() -> RepeatedRowOrder { - ::std::default::Default::default() - } - - // repeated .RowOrder items = 1; - - - pub fn get_items(&self) -> &[RowOrder] { - &self.items - } - pub fn clear_items(&mut self) { - self.items.clear(); - } - - // Param is passed by value, moved - pub fn set_items(&mut self, v: ::protobuf::RepeatedField) { - self.items = v; - } - - // Mutable pointer to the field. - pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.items - } - - // Take field - pub fn take_items(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for RepeatedRowOrder { - fn is_initialized(&self) -> bool { - for v in &self.items { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.items { - let len = value.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.items { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> RepeatedRowOrder { - RepeatedRowOrder::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "items", - |m: &RepeatedRowOrder| { &m.items }, - |m: &mut RepeatedRowOrder| { &mut m.items }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RepeatedRowOrder", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RepeatedRowOrder { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RepeatedRowOrder::new) - } -} - -impl ::protobuf::Clear for RepeatedRowOrder { - fn clear(&mut self) { - self.items.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RepeatedRowOrder { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RepeatedRowOrder { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct Row { // message fields @@ -2243,7 +2112,7 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockOrder { pub struct GridBlock { // message fields pub block_id: ::std::string::String, - pub row_ids: ::protobuf::RepeatedField<::std::string::String>, + pub row_orders: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -2286,34 +2155,39 @@ impl GridBlock { ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) } - // repeated string row_ids = 2; + // repeated .RowOrder row_orders = 2; - pub fn get_row_ids(&self) -> &[::std::string::String] { - &self.row_ids + pub fn get_row_orders(&self) -> &[RowOrder] { + &self.row_orders } - pub fn clear_row_ids(&mut self) { - self.row_ids.clear(); + pub fn clear_row_orders(&mut self) { + self.row_orders.clear(); } // Param is passed by value, moved - pub fn set_row_ids(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) { - self.row_ids = v; + pub fn set_row_orders(&mut self, v: ::protobuf::RepeatedField) { + self.row_orders = v; } // Mutable pointer to the field. - pub fn mut_row_ids(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> { - &mut self.row_ids + pub fn mut_row_orders(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.row_orders } // Take field - pub fn take_row_ids(&mut self) -> ::protobuf::RepeatedField<::std::string::String> { - ::std::mem::replace(&mut self.row_ids, ::protobuf::RepeatedField::new()) + pub fn take_row_orders(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.row_orders, ::protobuf::RepeatedField::new()) } } impl ::protobuf::Message for GridBlock { fn is_initialized(&self) -> bool { + for v in &self.row_orders { + if !v.is_initialized() { + return false; + } + }; true } @@ -2325,7 +2199,7 @@ impl ::protobuf::Message for GridBlock { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, 2 => { - ::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.row_ids)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.row_orders)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -2342,8 +2216,9 @@ impl ::protobuf::Message for GridBlock { if !self.block_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.block_id); } - for value in &self.row_ids { - my_size += ::protobuf::rt::string_size(2, &value); + for value in &self.row_orders { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -2354,8 +2229,10 @@ impl ::protobuf::Message for GridBlock { if !self.block_id.is_empty() { os.write_string(1, &self.block_id)?; } - for v in &self.row_ids { - os.write_string(2, &v)?; + for v in &self.row_orders { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; }; os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -2400,10 +2277,10 @@ impl ::protobuf::Message for GridBlock { |m: &GridBlock| { &m.block_id }, |m: &mut GridBlock| { &mut m.block_id }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_ids", - |m: &GridBlock| { &m.row_ids }, - |m: &mut GridBlock| { &mut m.row_ids }, + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "row_orders", + |m: &GridBlock| { &m.row_orders }, + |m: &mut GridBlock| { &mut m.row_orders }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "GridBlock", @@ -2422,7 +2299,7 @@ impl ::protobuf::Message for GridBlock { impl ::protobuf::Clear for GridBlock { fn clear(&mut self) { self.block_id.clear(); - self.row_ids.clear(); + self.row_orders.clear(); self.unknown_fields.clear(); } } @@ -4204,35 +4081,34 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\"-\n\rRepeatedField\ \x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12Re\ peatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\ - \x05items\"<\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05ro\ - wId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\"3\n\x10Repeate\ - dRowOrder\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05items\ - \"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12@\n\x10\ - cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByFieldIdEntryR\rcell\ - ByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\x06height\x1aG\n\x12\ - CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\ - \x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\")\n\x0bRep\ - eatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\x04.RowR\x05items\"5\n\ - \x11RepeatedGridBlock\x12\x20\n\x05items\x18\x01\x20\x03(\x0b2\n.GridBlo\ - ckR\x05items\"+\n\x0eGridBlockOrder\x12\x19\n\x08block_id\x18\x01\x20\ - \x01(\tR\x07blockId\"?\n\tGridBlock\x12\x19\n\x08block_id\x18\x01\x20\ - \x01(\tR\x07blockId\x12\x17\n\x07row_ids\x18\x02\x20\x03(\tR\x06rowIds\"\ - ;\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\ - \n\x07content\x18\x02\x20\x01(\tR\x07content\"+\n\x0cRepeatedCell\x12\ - \x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateG\ - ridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06Grid\ - Id\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\ - \x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayloa\ - d\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_ro\ - w_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\"d\ - \n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06grid\ - Id\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\"\\\n\x0fQueryRowPayload\x12\x17\n\ - \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\ - \x20\x01(\tR\x07blockId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\ - b\x06proto3\ + \x05items\"T\n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05ro\ + wId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06he\ + ight\x18\x03\x20\x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\ + \x18\x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\ + \x0b2\x17.Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\ + \x03\x20\x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03k\ + ey\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\ + \x05.CellR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\ + \x01\x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\ + \x05items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockO\ + rder\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\"P\n\tGridBloc\ + k\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_order\ + s\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\ + \x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\ + \x20\x01(\tR\x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\ + \x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\ + \x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05valu\ + e\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\"d\n\x11QueryField\ + Payload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfie\ + ld_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.GridBlockOrd\ + erR\x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\ + \x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07bloc\ + kId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowIdb\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 2e85b13411..2ce7c429d5 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 @@ -27,9 +27,7 @@ message RepeatedFieldOrder { message RowOrder { string row_id = 1; string block_id = 2; -} -message RepeatedRowOrder { - repeated RowOrder items = 1; + int32 height = 3; } message Row { string id = 1; @@ -47,7 +45,7 @@ message GridBlockOrder { } message GridBlock { string block_id = 1; - repeated string row_ids = 2; + repeated RowOrder row_orders = 2; } message Cell { string field_id = 1;