From 84afc50cd30f2f84043959067d21816f991baf7d Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 2 Mar 2022 11:38:22 +0800 Subject: [PATCH 01/17] chore: rename classes --- frontend/app_flowy/lib/plugin/plugin.dart | 37 ++++++++++++++----- .../lib/startup/tasks/load_plugin.dart | 19 ---------- .../workspace/application/menu/menu_bloc.dart | 1 - .../presentation/home/home_stack.dart | 19 +++++----- .../presentation/home/menu/menu.dart | 2 +- .../presentation/home/navigation.dart | 6 +-- .../presentation/plugins/blank/blank.dart | 10 ++--- .../presentation/plugins/doc/document.dart | 26 ++++++------- .../presentation/plugins/trash/menu.dart | 1 - .../presentation/plugins/trash/trash.dart | 10 ++--- frontend/rust-lib/flowy-sdk/src/lib.rs | 2 +- 11 files changed, 59 insertions(+), 74 deletions(-) diff --git a/frontend/app_flowy/lib/plugin/plugin.dart b/frontend/app_flowy/lib/plugin/plugin.dart index d46e14746f..d0effa0e6d 100644 --- a/frontend/app_flowy/lib/plugin/plugin.dart +++ b/frontend/app_flowy/lib/plugin/plugin.dart @@ -3,27 +3,43 @@ library flowy_plugin; import 'package:app_flowy/plugin/plugin.dart'; import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; +import 'package:flowy_infra/notifier.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flutter/widgets.dart'; export "./src/sandbox.dart"; +enum DefaultPlugin { + quillEditor, + blank, + trash, +} + +extension FlowyDefaultPluginExt on DefaultPlugin { + int type() { + switch (this) { + case DefaultPlugin.quillEditor: + return 0; + case DefaultPlugin.blank: + return 1; + case DefaultPlugin.trash: + return 2; + } + } +} + typedef PluginType = int; - typedef PluginDataType = ViewDataType; - typedef PluginId = String; abstract class Plugin { - PluginId get pluginId; + PluginId get id; - PluginDisplay get pluginDisplay; + PluginDisplay get display; - PluginType get pluginType; + PluginType get ty; - ChangeNotifier? get displayNotifier => null; - - void dispose(); + void dispose() {} } abstract class PluginBuilder { @@ -37,10 +53,11 @@ abstract class PluginBuilder { } abstract class PluginConfig { + // Return false will disable the user to create it. For example, a trash plugin shouldn't be created by the user, bool get creatable => true; } -abstract class PluginDisplay with NavigationItem { +abstract class PluginDisplay with NavigationItem { @override Widget get leftBarItem; @@ -49,6 +66,8 @@ abstract class PluginDisplay with NavigationItem { List get navigationItems; + PublishNotifier? get notifier => null; + Widget buildWidget(); } diff --git a/frontend/app_flowy/lib/startup/tasks/load_plugin.dart b/frontend/app_flowy/lib/startup/tasks/load_plugin.dart index 650dd49d22..266c6d1c09 100644 --- a/frontend/app_flowy/lib/startup/tasks/load_plugin.dart +++ b/frontend/app_flowy/lib/startup/tasks/load_plugin.dart @@ -4,25 +4,6 @@ import 'package:app_flowy/workspace/presentation/plugins/blank/blank.dart'; import 'package:app_flowy/workspace/presentation/plugins/doc/document.dart'; import 'package:app_flowy/workspace/presentation/plugins/trash/trash.dart'; -enum DefaultPlugin { - quillEditor, - blank, - trash, -} - -extension FlowyDefaultPluginExt on DefaultPlugin { - int type() { - switch (this) { - case DefaultPlugin.quillEditor: - return 0; - case DefaultPlugin.blank: - return 1; - case DefaultPlugin.trash: - return 2; - } - } -} - class PluginLoadTask extends LaunchTask { @override LaunchTaskType get type => LaunchTaskType.dataProcessing; diff --git a/frontend/app_flowy/lib/workspace/application/menu/menu_bloc.dart b/frontend/app_flowy/lib/workspace/application/menu/menu_bloc.dart index 0ea811711e..6ee18986b5 100644 --- a/frontend/app_flowy/lib/workspace/application/menu/menu_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/menu/menu_bloc.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'package:app_flowy/plugin/plugin.dart'; -import 'package:app_flowy/startup/tasks/load_plugin.dart'; import 'package:app_flowy/workspace/application/workspace/workspace_listener.dart'; import 'package:app_flowy/workspace/application/workspace/workspace_service.dart'; import 'package:dartz/dartz.dart'; 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 6127440a89..3344b2793a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/home_stack.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/home_stack.dart @@ -8,7 +8,6 @@ import 'package:time/time.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:app_flowy/plugin/plugin.dart'; -import 'package:app_flowy/startup/tasks/load_plugin.dart'; import 'package:app_flowy/workspace/presentation/plugins/blank/blank.dart'; import 'package:app_flowy/workspace/presentation/home/home_sizes.dart'; import 'package:app_flowy/workspace/presentation/home/navigation.dart'; @@ -108,20 +107,20 @@ class HomeStackNotifier extends ChangeNotifier { Plugin _plugin; PublishNotifier collapsedNotifier = PublishNotifier(); - Widget get titleWidget => _plugin.pluginDisplay.leftBarItem; + Widget get titleWidget => _plugin.display.leftBarItem; HomeStackNotifier({Plugin? plugin}) : _plugin = plugin ?? makePlugin(pluginType: DefaultPlugin.blank.type()); set plugin(Plugin newPlugin) { - if (newPlugin.pluginId == _plugin.pluginId) { + if (newPlugin.id == _plugin.id) { return; } - _plugin.displayNotifier?.removeListener(notifyListeners); + _plugin.display.notifier?.removeListener(notifyListeners); _plugin.dispose(); _plugin = newPlugin; - _plugin.displayNotifier?.addListener(notifyListeners); + _plugin.display.notifier?.addListener(notifyListeners); notifyListeners(); } @@ -134,7 +133,7 @@ class HomeStackManager { HomeStackManager(); Widget title() { - return _notifier.plugin.pluginDisplay.leftBarItem; + return _notifier.plugin.display.leftBarItem; } PublishNotifier get collapsedNotifier => _notifier.collapsedNotifier; @@ -166,10 +165,10 @@ class HomeStackManager { ], child: Consumer(builder: (ctx, HomeStackNotifier notifier, child) { return FadingIndexedStack( - index: getIt().indexOf(notifier.plugin.pluginType), + index: getIt().indexOf(notifier.plugin.ty), children: getIt().supportPluginTypes.map((pluginType) { - if (pluginType == notifier.plugin.pluginType) { - return notifier.plugin.pluginDisplay.buildWidget(); + if (pluginType == notifier.plugin.ty) { + return notifier.plugin.display.buildWidget(); } else { return const BlankStackPage(); } @@ -198,7 +197,7 @@ class HomeTopBar extends StatelessWidget { value: Provider.of(context, listen: false), child: Consumer( builder: (BuildContext context, HomeStackNotifier notifier, Widget? child) { - return notifier.plugin.pluginDisplay.rightBarItem ?? const SizedBox(); + return notifier.plugin.display.rightBarItem ?? const SizedBox(); }, ), ) // _renderMoreButton(), diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart index eeebf2b145..73771596cb 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart @@ -55,7 +55,7 @@ class HomeMenu extends StatelessWidget { child: MultiBlocListener( listeners: [ BlocListener( - listenWhen: (p, c) => p.plugin.pluginId != c.plugin.pluginId, + listenWhen: (p, c) => p.plugin.id != c.plugin.id, listener: (context, state) { getIt().setPlugin(state.plugin); }, diff --git a/frontend/app_flowy/lib/workspace/presentation/home/navigation.dart b/frontend/app_flowy/lib/workspace/presentation/home/navigation.dart index e8a9c3d457..511b94db90 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/navigation.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/navigation.dart @@ -17,8 +17,8 @@ class NavigationNotifier with ChangeNotifier { void update(HomeStackNotifier notifier) { bool shouldNotify = false; - if (navigationItems != notifier.plugin.pluginDisplay.navigationItems) { - navigationItems = notifier.plugin.pluginDisplay.navigationItems; + if (navigationItems != notifier.plugin.display.navigationItems) { + navigationItems = notifier.plugin.display.navigationItems; shouldNotify = true; } @@ -59,7 +59,7 @@ class FlowyNavigation extends StatelessWidget { create: (_) { final notifier = Provider.of(context, listen: false); return NavigationNotifier( - navigationItems: notifier.plugin.pluginDisplay.navigationItems, + navigationItems: notifier.plugin.display.navigationItems, collapasedNotifier: notifier.collapsedNotifier, ); }, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/blank/blank.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/blank/blank.dart index 4534053ad8..6be2a788fb 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/blank/blank.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/blank/blank.dart @@ -1,4 +1,3 @@ -import 'package:app_flowy/startup/tasks/load_plugin.dart'; import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; @@ -32,16 +31,13 @@ class BlankPagePlugin extends Plugin { }) : _pluginType = pluginType; @override - void dispose() {} + PluginDisplay get display => BlankPagePluginDisplay(); @override - PluginDisplay get pluginDisplay => BlankPagePluginDisplay(); + PluginId get id => "BlankStack"; @override - PluginId get pluginId => "BlankStack"; - - @override - PluginType get pluginType => _pluginType; + PluginType get ty => _pluginType; } class BlankPagePluginDisplay extends PluginDisplay { 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 021478866a..72465dd54b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart @@ -7,7 +7,6 @@ export './src/widget/toolbar/tool_bar.dart'; import 'package:app_flowy/plugin/plugin.dart'; import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/startup/tasks/load_plugin.dart'; import 'package:app_flowy/workspace/application/appearance.dart'; import 'package:app_flowy/workspace/application/doc/share_bloc.dart'; import 'package:app_flowy/workspace/application/view/view_listener.dart'; @@ -16,6 +15,7 @@ import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart'; import 'package:app_flowy/workspace/presentation/widgets/pop_up_action.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/notifier.dart'; import 'package:flowy_infra/size.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; @@ -56,7 +56,6 @@ class DocumentPluginBuilder extends PluginBuilder { class DocumentPlugin implements Plugin { late View _view; ViewListener? _listener; - final ValueNotifier _displayNotifier = ValueNotifier(0); late PluginType _pluginType; DocumentPlugin({required PluginType pluginType, required View view, Key? key}) : _view = view { @@ -66,7 +65,7 @@ class DocumentPlugin implements Plugin { result.fold( (newView) { _view = newView; - _displayNotifier.value = _view.hashCode; + display.notifier!.value = _view.hashCode; }, (error) {}, ); @@ -81,19 +80,17 @@ class DocumentPlugin implements Plugin { } @override - PluginDisplay get pluginDisplay => DocumentPluginDisplay(view: _view); + PluginDisplay get display => DocumentPluginDisplay(view: _view); @override - PluginType get pluginType => _pluginType; + PluginType get ty => _pluginType; @override - PluginId get pluginId => _view.id; - - @override - ChangeNotifier? get displayNotifier => _displayNotifier; + PluginId get id => _view.id; } -class DocumentPluginDisplay extends PluginDisplay { +class DocumentPluginDisplay extends PluginDisplay { + final PublishNotifier _displayNotifier = PublishNotifier(); final View _view; DocumentPluginDisplay({required View view, Key? key}) : _view = view; @@ -110,6 +107,9 @@ class DocumentPluginDisplay extends PluginDisplay { @override List get navigationItems => _makeNavigationItems(); + @override + PublishNotifier? get notifier => _displayNotifier; + List _makeNavigationItems() { return [ this, @@ -257,7 +257,7 @@ class DocumentShareButton extends StatelessWidget { context.read().add(const DocShareEvent.shareMarkdown()); break; case ShareAction.copyLink: - showWorkInProgressDialog(context); + FlowyAlertDialog(title: LocaleKeys.shareAction_workInProgress.tr()).show(context); break; } }); @@ -269,10 +269,6 @@ class DocumentShareButton extends StatelessWidget { anchorOffset: offset, ); } - - void showWorkInProgressDialog(BuildContext context) { - FlowyAlertDialog(title: LocaleKeys.shareAction_workInProgress.tr()).show(context); - } } class ShareActions with ActionList implements FlowyOverlayDelegate { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/trash/menu.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/trash/menu.dart index 2053432264..ccd1c85188 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/trash/menu.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/trash/menu.dart @@ -1,6 +1,5 @@ import 'package:app_flowy/plugin/plugin.dart'; import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/startup/tasks/load_plugin.dart'; import 'package:app_flowy/workspace/application/appearance.dart'; import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:app_flowy/workspace/presentation/home/menu/menu.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/trash/trash.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/trash/trash.dart index b0324a1138..4f9ef4c911 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/trash/trash.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/trash/trash.dart @@ -4,7 +4,6 @@ export "./src/trash_header.dart"; import 'package:app_flowy/plugin/plugin.dart'; import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/startup/tasks/load_plugin.dart'; import 'package:app_flowy/workspace/application/trash/trash_bloc.dart'; import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -49,16 +48,13 @@ class TrashPlugin extends Plugin { TrashPlugin({required PluginType pluginType}) : _pluginType = pluginType; @override - void dispose() {} + PluginDisplay get display => TrashPluginDisplay(); @override - PluginDisplay get pluginDisplay => TrashPluginDisplay(); + PluginId get id => "TrashStack"; @override - PluginId get pluginId => "TrashStack"; - - @override - PluginType get pluginType => _pluginType; + PluginType get ty => _pluginType; } class TrashPluginDisplay extends PluginDisplay { diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index 16e3c37def..83a38111e7 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -76,7 +76,7 @@ fn crate_log_filter(level: String) -> String { filters.push(format!("dart_ffi={}", "info")); filters.push(format!("flowy_database={}", "info")); filters.push(format!("flowy_net={}", "info")); - filters.push(format!("flowy_sync={}", "trace")); + filters.push(format!("flowy_sync={}", "info")); filters.join(",") } From 5549cff1772e5582e248078ebb7d883e6682c263 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 2 Mar 2022 15:10:53 +0800 Subject: [PATCH 02/17] chore: add flowy-grid crate --- frontend/rust-lib/Cargo.lock | 4 ++++ frontend/rust-lib/Cargo.toml | 1 + frontend/rust-lib/flowy-grid/Cargo.toml | 8 ++++++++ frontend/rust-lib/flowy-grid/src/lib.rs | 8 ++++++++ frontend/rust-lib/flowy-sdk/src/lib.rs | 1 + 5 files changed, 22 insertions(+) create mode 100644 frontend/rust-lib/flowy-grid/Cargo.toml create mode 100644 frontend/rust-lib/flowy-grid/src/lib.rs diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 2ec1b6e3bd..b0eec95054 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1038,6 +1038,10 @@ dependencies = [ "uuid", ] +[[package]] +name = "flowy-grid" +version = "0.1.0" + [[package]] name = "flowy-net" version = "0.1.0" diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index ea37363bcc..84dcec26be 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -14,6 +14,7 @@ members = [ "flowy-block", "flowy-error", "flowy-sync", + "flowy-grid", ] [profile.dev] diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml new file mode 100644 index 0000000000..6043e37a69 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "flowy-grid" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/frontend/rust-lib/flowy-grid/src/lib.rs b/frontend/rust-lib/flowy-grid/src/lib.rs new file mode 100644 index 0000000000..1b4a90c938 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/lib.rs @@ -0,0 +1,8 @@ +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + let result = 2 + 2; + assert_eq!(result, 4); + } +} diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index 83a38111e7..a24c071943 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -77,6 +77,7 @@ fn crate_log_filter(level: String) -> String { filters.push(format!("flowy_database={}", "info")); filters.push(format!("flowy_net={}", "info")); filters.push(format!("flowy_sync={}", "info")); + filters.push(format!("flowy_sync={}", "info")); filters.join(",") } From 4187e99433042b95cdfac49fa136186df7651e0c Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 2 Mar 2022 21:12:21 +0800 Subject: [PATCH 03/17] feat: add grid struct --- .../flowy-collaboration/document_info.pb.dart | 58 +- .../document_info.pbjson.dart | 16 +- .../rust-lib/flowy-block/src/block_editor.rs | 2 +- frontend/rust-lib/flowy-block/src/lib.rs | 4 +- frontend/rust-lib/flowy-block/src/manager.rs | 10 +- .../flowy-net/src/http_server/document.rs | 8 +- .../flowy-net/src/local_server/server.rs | 6 +- shared-lib/Cargo.lock | 10 + shared-lib/Cargo.toml | 1 + .../src/entities/document_info.rs | 8 +- .../src/protobuf/model/document_info.rs | 145 +- .../src/protobuf/proto/document_info.proto | 6 +- .../src/server_document/document_manager.rs | 4 +- shared-lib/flowy-collaboration/src/util.rs | 2 +- .../flowy-derive/src/proto_buf/deserialize.rs | 7 +- .../flowy-derive/src/proto_buf/serialize.rs | 39 +- shared-lib/flowy-grid-data-model/Cargo.toml | 20 + shared-lib/flowy-grid-data-model/Flowy.toml | 3 + shared-lib/flowy-grid-data-model/build.rs | 5 + .../src/entities/grid.rs | 148 + .../flowy-grid-data-model/src/entities/mod.rs | 3 + shared-lib/flowy-grid-data-model/src/lib.rs | 2 + .../flowy-grid-data-model/src/protobuf/mod.rs | 4 + .../src/protobuf/model/grid.rs | 2811 +++++++++++++++++ .../src/protobuf/model/mod.rs | 5 + .../src/protobuf/proto/grid.proto | 64 + 26 files changed, 3233 insertions(+), 158 deletions(-) create mode 100644 shared-lib/flowy-grid-data-model/Cargo.toml create mode 100644 shared-lib/flowy-grid-data-model/Flowy.toml create mode 100644 shared-lib/flowy-grid-data-model/build.rs create mode 100644 shared-lib/flowy-grid-data-model/src/entities/grid.rs create mode 100644 shared-lib/flowy-grid-data-model/src/entities/mod.rs create mode 100644 shared-lib/flowy-grid-data-model/src/lib.rs create mode 100644 shared-lib/flowy-grid-data-model/src/protobuf/mod.rs create mode 100644 shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs create mode 100644 shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs create mode 100644 shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pb.dart index 968f76062a..c97753ae9b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pb.dart @@ -77,7 +77,7 @@ class CreateBlockParams extends $pb.GeneratedMessage { class BlockInfo extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlockInfo', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'docId') + ..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') @@ -86,14 +86,14 @@ class BlockInfo extends $pb.GeneratedMessage { BlockInfo._() : super(); factory BlockInfo({ - $core.String? docId, + $core.String? blockId, $core.String? text, $fixnum.Int64? revId, $fixnum.Int64? baseRevId, }) { final _result = create(); - if (docId != null) { - _result.docId = docId; + if (blockId != null) { + _result.blockId = blockId; } if (text != null) { _result.text = text; @@ -128,13 +128,13 @@ class BlockInfo extends $pb.GeneratedMessage { static BlockInfo? _defaultInstance; @$pb.TagNumber(1) - $core.String get docId => $_getSZ(0); + $core.String get blockId => $_getSZ(0); @$pb.TagNumber(1) - set docId($core.String v) { $_setString(0, v); } + set blockId($core.String v) { $_setString(0, v); } @$pb.TagNumber(1) - $core.bool hasDocId() => $_has(0); + $core.bool hasBlockId() => $_has(0); @$pb.TagNumber(1) - void clearDocId() => clearField(1); + void clearBlockId() => clearField(1); @$pb.TagNumber(2) $core.String get text => $_getSZ(1); @@ -164,56 +164,56 @@ class BlockInfo extends $pb.GeneratedMessage { void clearBaseRevId() => clearField(4); } -class ResetDocumentParams extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ResetDocumentParams', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'docId') +class ResetBlockParams extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ResetBlockParams', 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 ; - ResetDocumentParams._() : super(); - factory ResetDocumentParams({ - $core.String? docId, + ResetBlockParams._() : super(); + factory ResetBlockParams({ + $core.String? blockId, $0.RepeatedRevision? revisions, }) { final _result = create(); - if (docId != null) { - _result.docId = docId; + if (blockId != null) { + _result.blockId = blockId; } if (revisions != null) { _result.revisions = revisions; } return _result; } - factory ResetDocumentParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory ResetDocumentParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory ResetBlockParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ResetBlockParams.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') - ResetDocumentParams clone() => ResetDocumentParams()..mergeFromMessage(this); + ResetBlockParams clone() => ResetBlockParams()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - ResetDocumentParams copyWith(void Function(ResetDocumentParams) updates) => super.copyWith((message) => updates(message as ResetDocumentParams)) as ResetDocumentParams; // ignore: deprecated_member_use + ResetBlockParams copyWith(void Function(ResetBlockParams) updates) => super.copyWith((message) => updates(message as ResetBlockParams)) as ResetBlockParams; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static ResetDocumentParams create() => ResetDocumentParams._(); - ResetDocumentParams createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static ResetBlockParams create() => ResetBlockParams._(); + ResetBlockParams createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static ResetDocumentParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static ResetDocumentParams? _defaultInstance; + static ResetBlockParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ResetBlockParams? _defaultInstance; @$pb.TagNumber(1) - $core.String get docId => $_getSZ(0); + $core.String get blockId => $_getSZ(0); @$pb.TagNumber(1) - set docId($core.String v) { $_setString(0, v); } + set blockId($core.String v) { $_setString(0, v); } @$pb.TagNumber(1) - $core.bool hasDocId() => $_has(0); + $core.bool hasBlockId() => $_has(0); @$pb.TagNumber(1) - void clearDocId() => clearField(1); + void clearBlockId() => clearField(1); @$pb.TagNumber(2) $0.RepeatedRevision get revisions => $_getN(1); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbjson.dart index d25e3b92b4..e1f5900185 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbjson.dart @@ -23,7 +23,7 @@ final $typed_data.Uint8List createBlockParamsDescriptor = $convert.base64Decode( const BlockInfo$json = const { '1': 'BlockInfo', '2': const [ - const {'1': 'doc_id', '3': 1, '4': 1, '5': 9, '10': 'docId'}, + 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'}, @@ -31,18 +31,18 @@ const BlockInfo$json = const { }; /// Descriptor for `BlockInfo`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List blockInfoDescriptor = $convert.base64Decode('CglCbG9ja0luZm8SFQoGZG9jX2lkGAEgASgJUgVkb2NJZBISCgR0ZXh0GAIgASgJUgR0ZXh0EhUKBnJldl9pZBgDIAEoA1IFcmV2SWQSHgoLYmFzZV9yZXZfaWQYBCABKANSCWJhc2VSZXZJZA=='); -@$core.Deprecated('Use resetDocumentParamsDescriptor instead') -const ResetDocumentParams$json = const { - '1': 'ResetDocumentParams', +final $typed_data.Uint8List blockInfoDescriptor = $convert.base64Decode('CglCbG9ja0luZm8SGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSEgoEdGV4dBgCIAEoCVIEdGV4dBIVCgZyZXZfaWQYAyABKANSBXJldklkEh4KC2Jhc2VfcmV2X2lkGAQgASgDUgliYXNlUmV2SWQ='); +@$core.Deprecated('Use resetBlockParamsDescriptor instead') +const ResetBlockParams$json = const { + '1': 'ResetBlockParams', '2': const [ - const {'1': 'doc_id', '3': 1, '4': 1, '5': 9, '10': 'docId'}, + 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 `ResetDocumentParams`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List resetDocumentParamsDescriptor = $convert.base64Decode('ChNSZXNldERvY3VtZW50UGFyYW1zEhUKBmRvY19pZBgBIAEoCVIFZG9jSWQSLwoJcmV2aXNpb25zGAIgASgLMhEuUmVwZWF0ZWRSZXZpc2lvblIJcmV2aXNpb25z'); +/// Descriptor for `ResetBlockParams`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List resetBlockParamsDescriptor = $convert.base64Decode('ChBSZXNldEJsb2NrUGFyYW1zEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEi8KCXJldmlzaW9ucxgCIAEoCzIRLlJlcGVhdGVkUmV2aXNpb25SCXJldmlzaW9ucw=='); @$core.Deprecated('Use blockDeltaDescriptor instead') const BlockDelta$json = const { '1': 'BlockDelta', diff --git a/frontend/rust-lib/flowy-block/src/block_editor.rs b/frontend/rust-lib/flowy-block/src/block_editor.rs index 1ac0b99284..92f6217d2f 100644 --- a/frontend/rust-lib/flowy-block/src/block_editor.rs +++ b/frontend/rust-lib/flowy-block/src/block_editor.rs @@ -225,7 +225,7 @@ impl RevisionObjectBuilder for BlockInfoBuilder { correct_delta(&mut delta); Result::::Ok(BlockInfo { - doc_id: object_id.to_owned(), + block_id: object_id.to_owned(), text: delta.to_delta_json(), rev_id, base_rev_id, diff --git a/frontend/rust-lib/flowy-block/src/lib.rs b/frontend/rust-lib/flowy-block/src/lib.rs index 018bd94599..0995bd2136 100644 --- a/frontend/rust-lib/flowy-block/src/lib.rs +++ b/frontend/rust-lib/flowy-block/src/lib.rs @@ -11,7 +11,7 @@ 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, ResetDocumentParams}; +use flowy_collaboration::entities::document_info::{BlockId, BlockInfo, CreateBlockParams, ResetBlockParams}; use lib_infra::future::FutureResult; pub trait BlockCloudService: Send + Sync { @@ -19,5 +19,5 @@ pub trait BlockCloudService: Send + Sync { fn read_block(&self, token: &str, params: BlockId) -> FutureResult, FlowyError>; - fn update_block(&self, token: &str, params: ResetDocumentParams) -> FutureResult<(), FlowyError>; + fn update_block(&self, token: &str, params: ResetBlockParams) -> FutureResult<(), FlowyError>; } diff --git a/frontend/rust-lib/flowy-block/src/manager.rs b/frontend/rust-lib/flowy-block/src/manager.rs index 6f6ecf15c5..e7ad6f7494 100644 --- a/frontend/rust-lib/flowy-block/src/manager.rs +++ b/frontend/rust-lib/flowy-block/src/manager.rs @@ -162,8 +162,14 @@ impl RevisionCloudService for BlockRevisionCloudService { Some(doc) => { let delta_data = Bytes::from(doc.text.clone()); let doc_md5 = md5(&delta_data); - let revision = - Revision::new(&doc.doc_id, doc.base_rev_id, doc.rev_id, delta_data, &user_id, doc_md5); + let revision = Revision::new( + &doc.block_id, + doc.base_rev_id, + doc.rev_id, + delta_data, + &user_id, + doc_md5, + ); Ok(vec![revision]) } } 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 bbc5aa2824..e5be5ef6da 100644 --- a/frontend/rust-lib/flowy-net/src/http_server/document.rs +++ b/frontend/rust-lib/flowy-net/src/http_server/document.rs @@ -2,8 +2,8 @@ use crate::{ configuration::*, request::{HttpRequestBuilder, ResponseMiddleware}, }; -use flowy_block::BlockCloudService; -use flowy_collaboration::entities::document_info::{BlockId, BlockInfo, CreateBlockParams, ResetDocumentParams}; +use flowy_collaboration::entities::document_info::{BlockId, BlockInfo, CreateBlockParams, ResetBlockParams}; +use flowy_document::BlockCloudService; use flowy_error::FlowyError; use http_flowy::response::FlowyResponse; use lazy_static::lazy_static; @@ -33,7 +33,7 @@ impl BlockCloudService for BlockHttpCloudService { FutureResult::new(async move { read_document_request(&token, params, &url).await }) } - fn update_block(&self, token: &str, params: ResetDocumentParams) -> FutureResult<(), FlowyError> { + fn update_block(&self, token: &str, params: ResetBlockParams) -> FutureResult<(), FlowyError> { let token = token.to_owned(); let url = self.config.doc_url(); FutureResult::new(async move { reset_doc_request(&token, params, &url).await }) @@ -61,7 +61,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: ResetDocumentParams, url: &str) -> Result<(), FlowyError> { +pub async fn reset_doc_request(token: &str, params: ResetBlockParams, 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/server.rs b/frontend/rust-lib/flowy-net/src/local_server/server.rs index e81e08b80d..09724d2de5 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_delta_string, entities::{ - document_info::{BlockId, BlockInfo, CreateBlockParams, ResetDocumentParams}, + document_info::{BlockId, BlockInfo, CreateBlockParams, ResetBlockParams}, ws_data::{ClientRevisionWSData, ClientRevisionWSDataType}, }, errors::CollaborateError, @@ -416,7 +416,7 @@ impl BlockCloudService for LocalServer { fn read_block(&self, _token: &str, params: BlockId) -> FutureResult, FlowyError> { let doc = BlockInfo { - doc_id: params.value, + block_id: params.value, text: initial_delta_string(), rev_id: 0, base_rev_id: 0, @@ -424,7 +424,7 @@ impl BlockCloudService for LocalServer { FutureResult::new(async { Ok(Some(doc)) }) } - fn update_block(&self, _token: &str, _params: ResetDocumentParams) -> FutureResult<(), FlowyError> { + fn update_block(&self, _token: &str, _params: ResetBlockParams) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) } } diff --git a/shared-lib/Cargo.lock b/shared-lib/Cargo.lock index 18ade8da40..5b242f5fd6 100644 --- a/shared-lib/Cargo.lock +++ b/shared-lib/Cargo.lock @@ -478,6 +478,16 @@ dependencies = [ "uuid", ] +[[package]] +name = "flowy-grid-data-model" +version = "0.1.0" +dependencies = [ + "bytes", + "flowy-derive", + "lib-infra", + "protobuf", +] + [[package]] name = "flowy-user-data-model" version = "0.1.0" diff --git a/shared-lib/Cargo.toml b/shared-lib/Cargo.toml index 0a4b9c7069..3dca4e2f6d 100644 --- a/shared-lib/Cargo.toml +++ b/shared-lib/Cargo.toml @@ -9,6 +9,7 @@ members = [ "flowy-derive", "flowy-ast", "flowy-error-code", + "flowy-grid-data-model", ] [profile.dev] diff --git a/shared-lib/flowy-collaboration/src/entities/document_info.rs b/shared-lib/flowy-collaboration/src/entities/document_info.rs index a1cb853aab..1cb23027f5 100644 --- a/shared-lib/flowy-collaboration/src/entities/document_info.rs +++ b/shared-lib/flowy-collaboration/src/entities/document_info.rs @@ -17,7 +17,7 @@ pub struct CreateBlockParams { #[derive(ProtoBuf, Default, Debug, Clone, Eq, PartialEq)] pub struct BlockInfo { #[pb(index = 1)] - pub doc_id: String, + pub block_id: String, #[pb(index = 2)] pub text: String, @@ -49,7 +49,7 @@ impl std::convert::TryFrom for BlockInfo { let doc_json = delta.to_delta_json(); Ok(BlockInfo { - doc_id: revision.object_id, + block_id: revision.object_id, text: doc_json, rev_id: revision.rev_id, base_rev_id: revision.base_rev_id, @@ -58,9 +58,9 @@ impl std::convert::TryFrom for BlockInfo { } #[derive(ProtoBuf, Default, Debug, Clone)] -pub struct ResetDocumentParams { +pub struct ResetBlockParams { #[pb(index = 1)] - pub doc_id: String, + pub block_id: String, #[pb(index = 2)] pub revisions: RepeatedRevision, diff --git a/shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs b/shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs index 52b64df159..e2c9f5980c 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs +++ b/shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs @@ -242,7 +242,7 @@ impl ::protobuf::reflect::ProtobufValue for CreateBlockParams { #[derive(PartialEq,Clone,Default)] pub struct BlockInfo { // message fields - pub doc_id: ::std::string::String, + pub block_id: ::std::string::String, pub text: ::std::string::String, pub rev_id: i64, pub base_rev_id: i64, @@ -262,30 +262,30 @@ impl BlockInfo { ::std::default::Default::default() } - // string doc_id = 1; + // string block_id = 1; - pub fn get_doc_id(&self) -> &str { - &self.doc_id + pub fn get_block_id(&self) -> &str { + &self.block_id } - pub fn clear_doc_id(&mut self) { - self.doc_id.clear(); + pub fn clear_block_id(&mut self) { + self.block_id.clear(); } // Param is passed by value, moved - pub fn set_doc_id(&mut self, v: ::std::string::String) { - self.doc_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_doc_id(&mut self) -> &mut ::std::string::String { - &mut self.doc_id + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id } // Take field - pub fn take_doc_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.doc_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()) } // string text = 2; @@ -355,7 +355,7 @@ impl ::protobuf::Message for BlockInfo { 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.doc_id)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, 2 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.text)?; @@ -386,8 +386,8 @@ impl ::protobuf::Message for BlockInfo { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if !self.doc_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.doc_id); + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.block_id); } if !self.text.is_empty() { my_size += ::protobuf::rt::string_size(2, &self.text); @@ -404,8 +404,8 @@ impl ::protobuf::Message for BlockInfo { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.doc_id.is_empty() { - os.write_string(1, &self.doc_id)?; + if !self.block_id.is_empty() { + os.write_string(1, &self.block_id)?; } if !self.text.is_empty() { os.write_string(2, &self.text)?; @@ -455,9 +455,9 @@ impl ::protobuf::Message for BlockInfo { descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "doc_id", - |m: &BlockInfo| { &m.doc_id }, - |m: &mut BlockInfo| { &mut m.doc_id }, + "block_id", + |m: &BlockInfo| { &m.block_id }, + |m: &mut BlockInfo| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "text", @@ -490,7 +490,7 @@ impl ::protobuf::Message for BlockInfo { impl ::protobuf::Clear for BlockInfo { fn clear(&mut self) { - self.doc_id.clear(); + self.block_id.clear(); self.text.clear(); self.rev_id = 0; self.base_rev_id = 0; @@ -511,50 +511,50 @@ impl ::protobuf::reflect::ProtobufValue for BlockInfo { } #[derive(PartialEq,Clone,Default)] -pub struct ResetDocumentParams { +pub struct ResetBlockParams { // message fields - pub doc_id: ::std::string::String, + pub block_id: ::std::string::String, pub revisions: ::protobuf::SingularPtrField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a ResetDocumentParams { - fn default() -> &'a ResetDocumentParams { - ::default_instance() +impl<'a> ::std::default::Default for &'a ResetBlockParams { + fn default() -> &'a ResetBlockParams { + ::default_instance() } } -impl ResetDocumentParams { - pub fn new() -> ResetDocumentParams { +impl ResetBlockParams { + pub fn new() -> ResetBlockParams { ::std::default::Default::default() } - // string doc_id = 1; + // string block_id = 1; - pub fn get_doc_id(&self) -> &str { - &self.doc_id + pub fn get_block_id(&self) -> &str { + &self.block_id } - pub fn clear_doc_id(&mut self) { - self.doc_id.clear(); + pub fn clear_block_id(&mut self) { + self.block_id.clear(); } // Param is passed by value, moved - pub fn set_doc_id(&mut self, v: ::std::string::String) { - self.doc_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_doc_id(&mut self) -> &mut ::std::string::String { - &mut self.doc_id + pub fn mut_block_id(&mut self) -> &mut ::std::string::String { + &mut self.block_id } // Take field - pub fn take_doc_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.doc_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()) } // .RepeatedRevision revisions = 2; @@ -591,7 +591,7 @@ impl ResetDocumentParams { } } -impl ::protobuf::Message for ResetDocumentParams { +impl ::protobuf::Message for ResetBlockParams { fn is_initialized(&self) -> bool { for v in &self.revisions { if !v.is_initialized() { @@ -606,7 +606,7 @@ impl ::protobuf::Message for ResetDocumentParams { 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.doc_id)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, 2 => { ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.revisions)?; @@ -623,8 +623,8 @@ impl ::protobuf::Message for ResetDocumentParams { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if !self.doc_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.doc_id); + if !self.block_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.block_id); } if let Some(ref v) = self.revisions.as_ref() { let len = v.compute_size(); @@ -636,8 +636,8 @@ impl ::protobuf::Message for ResetDocumentParams { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.doc_id.is_empty() { - os.write_string(1, &self.doc_id)?; + if !self.block_id.is_empty() { + os.write_string(1, &self.block_id)?; } if let Some(ref v) = self.revisions.as_ref() { os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; @@ -674,8 +674,8 @@ impl ::protobuf::Message for ResetDocumentParams { Self::descriptor_static() } - fn new() -> ResetDocumentParams { - ResetDocumentParams::new() + fn new() -> ResetBlockParams { + ResetBlockParams::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -683,44 +683,44 @@ impl ::protobuf::Message for ResetDocumentParams { descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "doc_id", - |m: &ResetDocumentParams| { &m.doc_id }, - |m: &mut ResetDocumentParams| { &mut m.doc_id }, + "block_id", + |m: &ResetBlockParams| { &m.block_id }, + |m: &mut ResetBlockParams| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "revisions", - |m: &ResetDocumentParams| { &m.revisions }, - |m: &mut ResetDocumentParams| { &mut m.revisions }, + |m: &ResetBlockParams| { &m.revisions }, + |m: &mut ResetBlockParams| { &mut m.revisions }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "ResetDocumentParams", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "ResetBlockParams", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static ResetDocumentParams { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(ResetDocumentParams::new) + fn default_instance() -> &'static ResetBlockParams { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(ResetBlockParams::new) } } -impl ::protobuf::Clear for ResetDocumentParams { +impl ::protobuf::Clear for ResetBlockParams { fn clear(&mut self) { - self.doc_id.clear(); + self.block_id.clear(); self.revisions.clear(); self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for ResetDocumentParams { +impl ::std::fmt::Debug for ResetBlockParams { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for ResetDocumentParams { +impl ::protobuf::reflect::ProtobufValue for ResetBlockParams { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -1325,17 +1325,18 @@ impl ::protobuf::reflect::ProtobufValue for BlockId { 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\"m\n\tBlockInfo\x12\x15\ - \n\x06doc_id\x18\x01\x20\x01(\tR\x05docId\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\x13ResetDocu\ - mentParams\x12\x15\n\x06doc_id\x18\x01\x20\x01(\tR\x05docId\x12/\n\trevi\ - sions\x18\x02\x20\x01(\x0b2\x11.RepeatedRevisionR\trevisions\"F\n\nBlock\ - Delta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\x1d\n\nde\ - lta_json\x18\x02\x20\x01(\tR\tdeltaJson\"S\n\nNewDocUser\x12\x17\n\x07us\ - er_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\"\x1f\n\ - \x07BlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05valueb\x06proto3\ + \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\"F\n\ + \nBlockDelta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\ + \x1d\n\ndelta_json\x18\x02\x20\x01(\tR\tdeltaJson\"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\ "; 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/document_info.proto index 4e234478f2..32d6102c34 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/proto/document_info.proto +++ b/shared-lib/flowy-collaboration/src/protobuf/proto/document_info.proto @@ -6,13 +6,13 @@ message CreateBlockParams { RepeatedRevision revisions = 2; } message BlockInfo { - string doc_id = 1; + string block_id = 1; string text = 2; int64 rev_id = 3; int64 base_rev_id = 4; } -message ResetDocumentParams { - string doc_id = 1; +message ResetBlockParams { + string block_id = 1; RepeatedRevision revisions = 2; } message BlockDelta { 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 864840e9b5..37c3bf4f6a 100644 --- a/shared-lib/flowy-collaboration/src/server_document/document_manager.rs +++ b/shared-lib/flowy-collaboration/src/server_document/document_manager.rs @@ -206,7 +206,7 @@ struct OpenDocumentHandler { impl OpenDocumentHandler { fn new(doc: BlockInfo, persistence: Arc) -> Result { - let doc_id = doc.doc_id.clone(); + let doc_id = doc.block_id.clone(); let (sender, receiver) = mpsc::channel(1000); let users = DashMap::new(); @@ -214,7 +214,7 @@ impl OpenDocumentHandler { let sync_object = ServerDocument::from_delta(&doc_id, delta); let synchronizer = Arc::new(DocumentRevisionSynchronizer::new(doc.rev_id, sync_object, persistence)); - let queue = DocumentCommandRunner::new(&doc.doc_id, receiver, synchronizer); + let queue = DocumentCommandRunner::new(&doc.block_id, receiver, synchronizer); tokio::task::spawn(queue.run()); Ok(Self { doc_id, sender, users }) } diff --git a/shared-lib/flowy-collaboration/src/util.rs b/shared-lib/flowy-collaboration/src/util.rs index 07db9cdbce..79f7c28fd7 100644 --- a/shared-lib/flowy-collaboration/src/util.rs +++ b/shared-lib/flowy-collaboration/src/util.rs @@ -239,7 +239,7 @@ pub fn make_document_info_pb_from_revisions_pb( let text = document_delta.to_delta_json(); let mut block_info = BlockInfoPB::new(); - block_info.set_doc_id(doc_id.to_owned()); + block_info.set_block_id(doc_id.to_owned()); block_info.set_text(text); block_info.set_base_rev_id(base_rev_id); block_info.set_rev_id(rev_id); diff --git a/shared-lib/flowy-derive/src/proto_buf/deserialize.rs b/shared-lib/flowy-derive/src/proto_buf/deserialize.rs index 8971d326c2..a971279b21 100644 --- a/shared-lib/flowy-derive/src/proto_buf/deserialize.rs +++ b/shared-lib/flowy-derive/src/proto_buf/deserialize.rs @@ -207,13 +207,12 @@ fn token_stream_for_vec(ctxt: &Ctxt, member: &syn::Member, bracketed_type: &TyIn } } -fn token_stream_for_map(ctxt: &Ctxt, member: &syn::Member, bracketed_type: &TyInfo) -> Option { +fn token_stream_for_map(ctxt: &Ctxt, member: &syn::Member, ty_info: &TyInfo) -> Option { let ident = get_member_ident(ctxt, member)?; - let take_ident = format_ident!("take_{}", ident.to_string()); - let ty = bracketed_type.ty; + let ty = ty_info.ty; - match ident_category(bracketed_type.ident) { + match ident_category(ty_info.ident) { TypeCategory::Protobuf => Some(quote! { let mut m: std::collections::HashMap = std::collections::HashMap::new(); pb.#take_ident().into_iter().for_each(|(k,v)| { diff --git a/shared-lib/flowy-derive/src/proto_buf/serialize.rs b/shared-lib/flowy-derive/src/proto_buf/serialize.rs index d0162c90d3..eff797a310 100644 --- a/shared-lib/flowy-derive/src/proto_buf/serialize.rs +++ b/shared-lib/flowy-derive/src/proto_buf/serialize.rs @@ -89,7 +89,7 @@ fn gen_token_stream(ctxt: &Ctxt, member: &syn::Member, ty: &syn::Type, is_option } }?; match ident_category(ty_info.ident) { - TypeCategory::Array => token_stream_for_vec(ctxt, member, ty_info.ty), + TypeCategory::Array => token_stream_for_vec(ctxt, member, ty_info.bracket_ty_info.unwrap().ty), TypeCategory::Map => token_stream_for_map(ctxt, member, ty_info.bracket_ty_info.unwrap().ty), TypeCategory::Str => { if is_option { @@ -149,7 +149,6 @@ fn token_stream_for_vec(ctxt: &Ctxt, member: &syn::Member, ty: &syn::Type) -> Op // e.g. pub cells: HashMap fn token_stream_for_map(ctxt: &Ctxt, member: &syn::Member, ty: &syn::Type) -> Option { // The key of the hashmap must be string - let flowy_protobuf = format_ident!("flowy_protobuf"); let ty_info = match parse_ty(ctxt, ty) { Ok(ty_info) => ty_info, Err(e) => { @@ -157,27 +156,21 @@ fn token_stream_for_map(ctxt: &Ctxt, member: &syn::Member, ty: &syn::Type) -> Op panic!(); } }?; + let value_ty = ty_info.ty; match ident_category(ty_info.ident) { - TypeCategory::Protobuf => { - let value_type = ty_info.ident; - Some(quote! { - let mut m: std::collections::HashMap = std::collections::HashMap::new(); - self.#member.iter().for_each(|(k,v)| { - m.insert(k.clone(), v.try_into().unwrap()); - }); - pb.#member = m; - }) - } - - _ => { - let value_type = ty_info.ident; - Some(quote! { - let mut m: std::collections::HashMap = std::collections::HashMap::new(); - self.#member.iter().for_each(|(k,v)| { - m.insert(k.clone(), v.clone()); - }); - pb.#member = m; - }) - } + TypeCategory::Protobuf => Some(quote! { + let mut m: std::collections::HashMap = std::collections::HashMap::new(); + self.#member.into_iter().for_each(|(k,v)| { + m.insert(k.clone(), v.try_into().unwrap()); + }); + pb.#member = m; + }), + _ => Some(quote! { + let mut m: std::collections::HashMap = std::collections::HashMap::new(); + self.#member.iter().for_each(|(k,v)| { + m.insert(k.clone(), v.clone()); + }); + pb.#member = m; + }), } } diff --git a/shared-lib/flowy-grid-data-model/Cargo.toml b/shared-lib/flowy-grid-data-model/Cargo.toml new file mode 100644 index 0000000000..c929ab4b76 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "flowy-grid-data-model" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +flowy-derive = { path = "../flowy-derive" } +protobuf = {version = "2.18.0"} +bytes = "1.0" + +[build-dependencies] +lib-infra = { path = "../lib-infra", features = ["protobuf_file_gen"] } + +[features] +default = [] +backend = [] +frontend = [] +dart = ["lib-infra/dart"] \ No newline at end of file diff --git a/shared-lib/flowy-grid-data-model/Flowy.toml b/shared-lib/flowy-grid-data-model/Flowy.toml new file mode 100644 index 0000000000..5e88aadda5 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/Flowy.toml @@ -0,0 +1,3 @@ + +proto_crates = ["src/entities",] +event_files = [] \ No newline at end of file diff --git a/shared-lib/flowy-grid-data-model/build.rs b/shared-lib/flowy-grid-data-model/build.rs new file mode 100644 index 0000000000..7f06ab48c8 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/build.rs @@ -0,0 +1,5 @@ +use lib_infra::code_gen; + +fn main() { + code_gen::protobuf_file::gen(env!("CARGO_PKG_NAME"), "./src/protobuf/proto"); +} diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs new file mode 100644 index 0000000000..3e25199227 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -0,0 +1,148 @@ +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use std::collections::HashMap; + +#[derive(Debug, Default, ProtoBuf)] +pub struct Grid { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub filters: RepeatedGridFilter, + + #[pb(index = 3)] + pub field_orders: RepeatedFieldOrder, + + #[pb(index = 4)] + pub row_orders: RepeatedRowOrder, +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct GridFilter { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub name: String, + + #[pb(index = 3)] + pub desc: String, +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct RepeatedGridFilter { + #[pb(index = 1)] + pub items: Vec, +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct FieldOrder { + #[pb(index = 1)] + pub field_id: String, + + #[pb(index = 2)] + pub visibility: bool, + + #[pb(index = 3)] + pub width: i32, +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct RepeatedFieldOrder { + #[pb(index = 1)] + pub items: Vec, +} + +#[derive(Debug, 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 type_options: AnyData, +} + +#[derive(Debug, ProtoBuf_Enum)] +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 + } +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct AnyData { + #[pb(index = 1)] + pub type_url: String, + + #[pb(index = 2)] + pub value: Vec, +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct RowOrder { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub row_id: String, + + #[pb(index = 3)] + pub visibility: bool, +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct RepeatedRowOrder { + #[pb(index = 1)] + pub items: Vec, +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct Row { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub grid_id: String, + + #[pb(index = 3)] + pub modified_time: i64, + + #[pb(index = 4)] + pub cell_by_field_id: HashMap, +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct Cell { + #[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, +} diff --git a/shared-lib/flowy-grid-data-model/src/entities/mod.rs b/shared-lib/flowy-grid-data-model/src/entities/mod.rs new file mode 100644 index 0000000000..9ba72a1272 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/entities/mod.rs @@ -0,0 +1,3 @@ +mod grid; + +pub use grid::*; diff --git a/shared-lib/flowy-grid-data-model/src/lib.rs b/shared-lib/flowy-grid-data-model/src/lib.rs new file mode 100644 index 0000000000..85976edd74 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/lib.rs @@ -0,0 +1,2 @@ +pub mod entities; +pub mod protobuf; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/mod.rs b/shared-lib/flowy-grid-data-model/src/protobuf/mod.rs new file mode 100644 index 0000000000..da97aad28a --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/protobuf/mod.rs @@ -0,0 +1,4 @@ +#![cfg_attr(rustfmt, rustfmt::skip)] +// Auto-generated, do not edit +mod model; +pub use model::*; \ No newline at end of file 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 new file mode 100644 index 0000000000..77db4ecdb1 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs @@ -0,0 +1,2811 @@ +// 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 `grid.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 Grid { + // message fields + pub grid_id: ::std::string::String, + pub filters: ::protobuf::SingularPtrField, + pub field_orders: ::protobuf::SingularPtrField, + pub row_orders: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Grid { + fn default() -> &'a Grid { + ::default_instance() + } +} + +impl Grid { + pub fn new() -> Grid { + ::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()) + } + + // .RepeatedGridFilter filters = 2; + + + pub fn get_filters(&self) -> &RepeatedGridFilter { + self.filters.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_filters(&mut self) { + self.filters.clear(); + } + + pub fn has_filters(&self) -> bool { + self.filters.is_some() + } + + // Param is passed by value, moved + pub fn set_filters(&mut self, v: RepeatedGridFilter) { + self.filters = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_filters(&mut self) -> &mut RepeatedGridFilter { + if self.filters.is_none() { + self.filters.set_default(); + } + self.filters.as_mut().unwrap() + } + + // Take field + pub fn take_filters(&mut self) -> RepeatedGridFilter { + self.filters.take().unwrap_or_else(|| RepeatedGridFilter::new()) + } + + // .RepeatedFieldOrder field_orders = 3; + + + pub fn get_field_orders(&self) -> &RepeatedFieldOrder { + self.field_orders.as_ref().unwrap_or_else(|| ::default_instance()) + } + 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); + } + + // 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() + } + + // Take field + pub fn take_field_orders(&mut self) -> RepeatedFieldOrder { + self.field_orders.take().unwrap_or_else(|| RepeatedFieldOrder::new()) + } + + // .RepeatedRowOrder row_orders = 4; + + + pub fn get_row_orders(&self) -> &RepeatedRowOrder { + self.row_orders.as_ref().unwrap_or_else(|| ::default_instance()) + } + 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); + } + + // 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() + } + + // Take field + pub fn take_row_orders(&mut self) -> RepeatedRowOrder { + self.row_orders.take().unwrap_or_else(|| RepeatedRowOrder::new()) + } +} + +impl ::protobuf::Message for Grid { + fn is_initialized(&self) -> bool { + for v in &self.filters { + if !v.is_initialized() { + return false; + } + }; + for v in &self.field_orders { + if !v.is_initialized() { + return false; + } + }; + for v in &self.row_orders { + 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_singular_message_into(wire_type, is, &mut self.filters)?; + }, + 3 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.field_orders)?; + }, + 4 => { + ::protobuf::rt::read_singular_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())?; + }, + }; + } + ::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 Some(ref v) = self.filters.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if let Some(ref v) = self.field_orders.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if let Some(ref v) = self.row_orders.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.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if let Some(ref v) = self.filters.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.field_orders.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)?; + } + if let Some(ref v) = self.row_orders.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)?; + } + 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() -> Grid { + Grid::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: &Grid| { &m.grid_id }, + |m: &mut Grid| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "filters", + |m: &Grid| { &m.filters }, + |m: &mut Grid| { &mut m.filters }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_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>( + "row_orders", + |m: &Grid| { &m.row_orders }, + |m: &mut Grid| { &mut m.row_orders }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Grid", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Grid { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Grid::new) + } +} + +impl ::protobuf::Clear for Grid { + fn clear(&mut self) { + self.grid_id.clear(); + self.filters.clear(); + self.field_orders.clear(); + self.row_orders.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Grid { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Grid { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct GridFilter { + // message fields + pub id: ::std::string::String, + pub name: ::std::string::String, + pub desc: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridFilter { + fn default() -> &'a GridFilter { + ::default_instance() + } +} + +impl GridFilter { + pub fn new() -> GridFilter { + ::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()) + } +} + +impl ::protobuf::Message for GridFilter { + 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)?; + }, + _ => { + ::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); + } + 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)?; + } + 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() -> GridFilter { + GridFilter::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: &GridFilter| { &m.id }, + |m: &mut GridFilter| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &GridFilter| { &m.name }, + |m: &mut GridFilter| { &mut m.name }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "desc", + |m: &GridFilter| { &m.desc }, + |m: &mut GridFilter| { &mut m.desc }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridFilter", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridFilter { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridFilter::new) + } +} + +impl ::protobuf::Clear for GridFilter { + fn clear(&mut self) { + self.id.clear(); + self.name.clear(); + self.desc.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridFilter { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridFilter { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct RepeatedGridFilter { + // 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 RepeatedGridFilter { + fn default() -> &'a RepeatedGridFilter { + ::default_instance() + } +} + +impl RepeatedGridFilter { + pub fn new() -> RepeatedGridFilter { + ::std::default::Default::default() + } + + // repeated .GridFilter items = 1; + + + pub fn get_items(&self) -> &[GridFilter] { + &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 RepeatedGridFilter { + 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() -> RepeatedGridFilter { + RepeatedGridFilter::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: &RepeatedGridFilter| { &m.items }, + |m: &mut RepeatedGridFilter| { &mut m.items }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedGridFilter", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RepeatedGridFilter { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedGridFilter::new) + } +} + +impl ::protobuf::Clear for RepeatedGridFilter { + fn clear(&mut self) { + self.items.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RepeatedGridFilter { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RepeatedGridFilter { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct FieldOrder { + // message fields + pub field_id: ::std::string::String, + 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 FieldOrder { + fn default() -> &'a FieldOrder { + ::default_instance() + } +} + +impl FieldOrder { + pub fn new() -> FieldOrder { + ::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()) + } + + // 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; + } + + // int32 width = 3; + + + 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 FieldOrder { + 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.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; + }, + 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.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.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.field_id); + } + if self.visibility != false { + my_size += 2; + } + if self.width != 0 { + my_size += ::protobuf::rt::value_size(3, 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.field_id.is_empty() { + os.write_string(1, &self.field_id)?; + } + if self.visibility != false { + os.write_bool(2, self.visibility)?; + } + if self.width != 0 { + os.write_int32(3, 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() -> FieldOrder { + FieldOrder::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: &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 }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "width", + |m: &FieldOrder| { &m.width }, + |m: &mut FieldOrder| { &mut m.width }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "FieldOrder", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static FieldOrder { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(FieldOrder::new) + } +} + +impl ::protobuf::Clear for FieldOrder { + fn clear(&mut self) { + self.field_id.clear(); + self.visibility = false; + self.width = 0; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for FieldOrder { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for FieldOrder { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct RepeatedFieldOrder { + // 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 RepeatedFieldOrder { + fn default() -> &'a RepeatedFieldOrder { + ::default_instance() + } +} + +impl RepeatedFieldOrder { + pub fn new() -> RepeatedFieldOrder { + ::std::default::Default::default() + } + + // repeated .FieldOrder items = 1; + + + pub fn get_items(&self) -> &[FieldOrder] { + &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 RepeatedFieldOrder { + 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() -> RepeatedFieldOrder { + RepeatedFieldOrder::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: &RepeatedFieldOrder| { &m.items }, + |m: &mut RepeatedFieldOrder| { &mut m.items }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedFieldOrder", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RepeatedFieldOrder { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedFieldOrder::new) + } +} + +impl ::protobuf::Clear for RepeatedFieldOrder { + fn clear(&mut self) { + self.items.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RepeatedFieldOrder { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RepeatedFieldOrder { + 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 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; + } + + // .AnyData type_options = 6; + + + 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 => { + ::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 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 let Some(ref v) = self.type_options.as_ref() { + os.write_tag(6, ::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_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.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 AnyData { + // message fields + pub type_url: ::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_url = 1; + + + pub fn get_type_url(&self) -> &str { + &self.type_url + } + pub fn clear_type_url(&mut self) { + self.type_url.clear(); + } + + // Param is passed by value, moved + pub fn set_type_url(&mut self, v: ::std::string::String) { + self.type_url = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_type_url(&mut self) -> &mut ::std::string::String { + &mut self.type_url + } + + // Take field + pub fn take_type_url(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.type_url, ::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_url)?; + }, + 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_url.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.type_url); + } + 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_url.is_empty() { + os.write_string(1, &self.type_url)?; + } + 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_url", + |m: &AnyData| { &m.type_url }, + |m: &mut AnyData| { &mut m.type_url }, + )); + 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_url.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, +} + +impl<'a> ::std::default::Default for &'a RowOrder { + fn default() -> &'a RowOrder { + ::default_instance() + } +} + +impl RowOrder { + pub fn new() -> 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; + + + 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()) + } + + // 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 { + 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.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())?; + }, + }; + } + ::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.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::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.row_id.is_empty() { + os.write_string(2, &self.row_id)?; + } + if self.visibility != false { + os.write_bool(3, 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() -> RowOrder { + RowOrder::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: &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, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RowOrder { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RowOrder::new) + } +} + +impl ::protobuf::Clear for RowOrder { + fn clear(&mut self) { + self.grid_id.clear(); + self.row_id.clear(); + self.visibility = false; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RowOrder { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RowOrder { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[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 + pub id: ::std::string::String, + pub grid_id: ::std::string::String, + pub modified_time: i64, + pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, Cell>, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Row { + fn default() -> &'a Row { + ::default_instance() + } +} + +impl Row { + pub fn new() -> Row { + ::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()) + } + + // int64 modified_time = 3; + + + pub fn get_modified_time(&self) -> i64 { + self.modified_time + } + pub fn clear_modified_time(&mut self) { + self.modified_time = 0; + } + + // Param is passed by value, moved + pub fn set_modified_time(&mut self, v: i64) { + self.modified_time = v; + } + + // repeated .Row.CellByFieldIdEntry cell_by_field_id = 4; + + + pub fn get_cell_by_field_id(&self) -> &::std::collections::HashMap<::std::string::String, Cell> { + &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, Cell>) { + 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, Cell> { + &mut self.cell_by_field_id + } + + // Take field + 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()) + } +} + +impl ::protobuf::Message for Row { + 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 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int64()?; + self.modified_time = tmp; + }, + 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.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.modified_time != 0 { + my_size += ::protobuf::rt::value_size(3, self.modified_time, ::protobuf::wire_format::WireTypeVarint); + } + my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(4, &self.cell_by_field_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.id.is_empty() { + os.write_string(1, &self.id)?; + } + if !self.grid_id.is_empty() { + os.write_string(2, &self.grid_id)?; + } + if self.modified_time != 0 { + os.write_int64(3, self.modified_time)?; + } + ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(4, &self.cell_by_field_id, 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() -> Row { + Row::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: &Row| { &m.id }, + |m: &mut Row| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &Row| { &m.grid_id }, + |m: &mut Row| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( + "modified_time", + |m: &Row| { &m.modified_time }, + |m: &mut Row| { &mut m.modified_time }, + )); + fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( + "cell_by_field_id", + |m: &Row| { &m.cell_by_field_id }, + |m: &mut Row| { &mut m.cell_by_field_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Row", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Row { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Row::new) + } +} + +impl ::protobuf::Clear for Row { + fn clear(&mut self) { + self.id.clear(); + self.grid_id.clear(); + self.modified_time = 0; + self.cell_by_field_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Row { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Row { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct Cell { + // message fields + pub id: ::std::string::String, + pub row_id: ::std::string::String, + pub field_id: ::std::string::String, + pub data: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Cell { + fn default() -> &'a Cell { + ::default_instance() + } +} + +impl Cell { + pub fn new() -> 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 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()) + } +} + +impl ::protobuf::Message for Cell { + 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)?; + }, + _ => { + ::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; + } + 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)?; + } + 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() -> Cell { + Cell::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: &Cell| { &m.id }, + |m: &mut Cell| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &Cell| { &m.row_id }, + |m: &mut Cell| { &mut m.row_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &Cell| { &m.field_id }, + |m: &mut Cell| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "data", + |m: &Cell| { &m.data }, + |m: &mut Cell| { &mut m.data }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Cell", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Cell { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Cell::new) + } +} + +impl ::protobuf::Clear for Cell { + 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 Cell { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Cell { + 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\ngrid.proto\"\xb8\x01\n\x04Grid\x12\x17\n\x07grid_id\x18\x01\x20\x01(\ + \tR\x06gridId\x12-\n\x07filters\x18\x02\x20\x01(\x0b2\x13.RepeatedGridFi\ + lterR\x07filters\x126\n\x0cfield_orders\x18\x03\x20\x01(\x0b2\x13.Repeat\ + edFieldOrderR\x0bfieldOrders\x120\n\nrow_orders\x18\x04\x20\x01(\x0b2\ + \x11.RepeatedRowOrderR\trowOrders\"D\n\nGridFilter\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\"7\n\x12RepeatedGridFilter\ + \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.GridFilterR\x05items\"]\n\nFi\ + eldOrder\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x1e\n\ + \nvisibility\x18\x02\x20\x01(\x08R\nvisibility\x12\x14\n\x05width\x18\ + \x03\x20\x01(\x05R\x05width\"7\n\x12RepeatedFieldOrder\x12!\n\x05items\ + \x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"\xaf\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+\n\x0ctype_options\x18\x06\x20\x01(\ + \x0b2\x08.AnyDataR\x0btypeOptions\":\n\x07AnyData\x12\x19\n\x08type_url\ + \x18\x01\x20\x01(\tR\x07typeUrl\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\ + \x05value\"Z\n\x08RowOrder\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06g\ + ridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x1e\n\nvisibi\ + lity\x18\x03\x20\x01(\x08R\nvisibility\"3\n\x10RepeatedRowOrder\x12\x1f\ + \n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05items\"\xde\x01\n\x03Ro\ + w\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\ + \x20\x01(\tR\x06gridId\x12#\n\rmodified_time\x18\x03\x20\x01(\x03R\x0cmo\ + difiedTime\x12@\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2\x17.Row.Cell\ + ByFieldIdEntryR\rcellByFieldId\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\"f\n\x04Cell\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*d\n\tFieldType\x12\x0c\n\x08Rich\ + Text\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; + +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 new file mode 100644 index 0000000000..7b56c6cee8 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs @@ -0,0 +1,5 @@ +#![cfg_attr(rustfmt, rustfmt::skip)] +// Auto-generated, do not edit + +mod grid; +pub use grid::*; 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 new file mode 100644 index 0000000000..c4947247a9 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto @@ -0,0 +1,64 @@ +syntax = "proto3"; + +message Grid { + string grid_id = 1; + RepeatedGridFilter filters = 2; + RepeatedFieldOrder field_orders = 3; + RepeatedRowOrder row_orders = 4; +} +message GridFilter { + string id = 1; + string name = 2; + string desc = 3; +} +message RepeatedGridFilter { + repeated GridFilter items = 1; +} +message FieldOrder { + string field_id = 1; + bool visibility = 2; + int32 width = 3; +} +message RepeatedFieldOrder { + repeated FieldOrder items = 1; +} +message Field { + string id = 1; + string name = 2; + string desc = 3; + FieldType field_type = 4; + bool frozen = 5; + AnyData type_options = 6; +} +message AnyData { + string type_url = 1; + bytes value = 2; +} +message RowOrder { + string grid_id = 1; + string row_id = 2; + bool visibility = 3; +} +message RepeatedRowOrder { + repeated RowOrder items = 1; +} +message Row { + string id = 1; + string grid_id = 2; + int64 modified_time = 3; + map cell_by_field_id = 4; +} +message Cell { + string id = 1; + string row_id = 2; + string field_id = 3; + AnyData data = 4; +} +enum FieldType { + RichText = 0; + Number = 1; + DateTime = 2; + SingleSelect = 3; + MultiSelect = 4; + Checkbox = 5; +} From 03f34b143d6bb4e1f021a17edcf5d8addaef1b24 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 2 Mar 2022 22:43:04 +0800 Subject: [PATCH 04/17] feat: add grid event --- .../dart_event/flowy-grid/dart_event.dart | 37 + .../flowy-grid-data-model/grid.pb.dart | 907 ++++++++++++++++++ .../flowy-grid-data-model/grid.pbenum.dart | 34 + .../flowy-grid-data-model/grid.pbjson.dart | 187 ++++ .../flowy-grid-data-model/grid.pbserver.dart | 9 + .../flowy-grid-data-model/protobuf.dart | 2 + .../lib/protobuf/flowy-grid/event_map.pb.dart | 11 + .../protobuf/flowy-grid/event_map.pbenum.dart | 26 + .../protobuf/flowy-grid/event_map.pbjson.dart | 21 + .../flowy-grid/event_map.pbserver.dart | 9 + .../lib/protobuf/flowy-grid/protobuf.dart | 2 + frontend/rust-lib/Cargo.lock | 22 + frontend/rust-lib/flowy-folder/Cargo.toml | 8 +- frontend/rust-lib/flowy-grid/Cargo.toml | 17 + frontend/rust-lib/flowy-grid/Flowy.toml | 3 + frontend/rust-lib/flowy-grid/build.rs | 7 + .../rust-lib/flowy-grid/src/controller.rs | 1 + .../rust-lib/flowy-grid/src/event_handler.rs | 23 + frontend/rust-lib/flowy-grid/src/event_map.rs | 26 + frontend/rust-lib/flowy-grid/src/lib.rs | 13 +- .../rust-lib/flowy-grid/src/protobuf/mod.rs | 4 + .../src/protobuf/model/event_map.rs | 91 ++ .../flowy-grid/src/protobuf/model/mod.rs | 5 + .../src/protobuf/proto/event_map.proto | 6 + frontend/rust-lib/flowy-sdk/Cargo.toml | 3 +- .../src/entities/grid.rs | 12 + .../src/protobuf/model/grid.rs | 324 ++++++- .../src/protobuf/proto/grid.proto | 6 + 28 files changed, 1801 insertions(+), 15 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart create mode 100644 frontend/rust-lib/flowy-grid/Flowy.toml create mode 100644 frontend/rust-lib/flowy-grid/build.rs create mode 100644 frontend/rust-lib/flowy-grid/src/controller.rs create mode 100644 frontend/rust-lib/flowy-grid/src/event_handler.rs create mode 100644 frontend/rust-lib/flowy-grid/src/event_map.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/mod.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto 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 new file mode 100644 index 0000000000..1c6420c126 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart @@ -0,0 +1,37 @@ + +/// Auto generate. Do not edit +part of '../../dispatch.dart'; +class GridEventCreateGrid { + CreateGridPayload request; + GridEventCreateGrid(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.CreateGrid.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (okBytes) => left(Grid.fromBuffer(okBytes)), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + +class GridEventOpenGrid { + GridId request; + GridEventOpenGrid(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.OpenGrid.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (okBytes) => left(Grid.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 new file mode 100644 index 0000000000..3fce9f98db --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart @@ -0,0 +1,907 @@ +/// +// Generated code. Do not modify. +// source: grid.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 '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') ? '' : 'gridId') + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'filters', subBuilder: RepeatedGridFilter.create) + ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', subBuilder: RepeatedFieldOrder.create) + ..aOM(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', subBuilder: RepeatedRowOrder.create) + ..hasRequiredFields = false + ; + + Grid._() : super(); + factory Grid({ + $core.String? gridId, + RepeatedGridFilter? filters, + RepeatedFieldOrder? fieldOrders, + RepeatedRowOrder? rowOrders, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (filters != null) { + _result.filters = filters; + } + if (fieldOrders != null) { + _result.fieldOrders = fieldOrders; + } + if (rowOrders != null) { + _result.rowOrders = rowOrders; + } + return _result; + } + factory Grid.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Grid.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') + Grid clone() => Grid()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Grid copyWith(void Function(Grid) updates) => super.copyWith((message) => updates(message as Grid)) as Grid; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Grid create() => Grid._(); + Grid createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Grid getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Grid? _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) + RepeatedGridFilter get filters => $_getN(1); + @$pb.TagNumber(2) + set filters(RepeatedGridFilter v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasFilters() => $_has(1); + @$pb.TagNumber(2) + void clearFilters() => clearField(2); + @$pb.TagNumber(2) + RepeatedGridFilter ensureFilters() => $_ensure(1); + + @$pb.TagNumber(3) + RepeatedFieldOrder get fieldOrders => $_getN(2); + @$pb.TagNumber(3) + set fieldOrders(RepeatedFieldOrder v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasFieldOrders() => $_has(2); + @$pb.TagNumber(3) + void clearFieldOrders() => clearField(3); + @$pb.TagNumber(3) + RepeatedFieldOrder ensureFieldOrders() => $_ensure(2); + + @$pb.TagNumber(4) + RepeatedRowOrder get rowOrders => $_getN(3); + @$pb.TagNumber(4) + set rowOrders(RepeatedRowOrder v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasRowOrders() => $_has(3); + @$pb.TagNumber(4) + void clearRowOrders() => clearField(4); + @$pb.TagNumber(4) + RepeatedRowOrder ensureRowOrders() => $_ensure(3); +} + +class GridFilter extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridFilter', 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') + ..hasRequiredFields = false + ; + + GridFilter._() : super(); + factory GridFilter({ + $core.String? id, + $core.String? name, + $core.String? desc, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (name != null) { + _result.name = name; + } + if (desc != null) { + _result.desc = desc; + } + return _result; + } + factory GridFilter.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridFilter.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') + GridFilter clone() => GridFilter()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridFilter copyWith(void Function(GridFilter) updates) => super.copyWith((message) => updates(message as GridFilter)) as GridFilter; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridFilter create() => GridFilter._(); + GridFilter createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridFilter getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridFilter? _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); +} + +class RepeatedGridFilter extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedGridFilter', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: GridFilter.create) + ..hasRequiredFields = false + ; + + RepeatedGridFilter._() : super(); + factory RepeatedGridFilter({ + $core.Iterable? items, + }) { + final _result = create(); + if (items != null) { + _result.items.addAll(items); + } + return _result; + } + factory RepeatedGridFilter.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedGridFilter.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') + RepeatedGridFilter clone() => RepeatedGridFilter()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RepeatedGridFilter copyWith(void Function(RepeatedGridFilter) updates) => super.copyWith((message) => updates(message as RepeatedGridFilter)) as RepeatedGridFilter; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RepeatedGridFilter create() => RepeatedGridFilter._(); + RepeatedGridFilter createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RepeatedGridFilter getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedGridFilter? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get items => $_getList(0); +} + +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') + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) + ..hasRequiredFields = false + ; + + FieldOrder._() : super(); + factory FieldOrder({ + $core.String? fieldId, + $core.bool? visibility, + $core.int? width, + }) { + final _result = create(); + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (visibility != null) { + _result.visibility = visibility; + } + if (width != null) { + _result.width = width; + } + return _result; + } + factory FieldOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory FieldOrder.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') + FieldOrder clone() => FieldOrder()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + FieldOrder copyWith(void Function(FieldOrder) updates) => super.copyWith((message) => updates(message as FieldOrder)) as FieldOrder; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static FieldOrder create() => FieldOrder._(); + FieldOrder createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static FieldOrder getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static FieldOrder? _defaultInstance; + + @$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.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); + + @$pb.TagNumber(3) + $core.int get width => $_getIZ(2); + @$pb.TagNumber(3) + set width($core.int v) { $_setSignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasWidth() => $_has(2); + @$pb.TagNumber(3) + void clearWidth() => clearField(3); +} + +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) + ..hasRequiredFields = false + ; + + RepeatedFieldOrder._() : super(); + factory RepeatedFieldOrder({ + $core.Iterable? items, + }) { + final _result = create(); + if (items != null) { + _result.items.addAll(items); + } + return _result; + } + factory RepeatedFieldOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedFieldOrder.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') + RepeatedFieldOrder clone() => RepeatedFieldOrder()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RepeatedFieldOrder copyWith(void Function(RepeatedFieldOrder) updates) => super.copyWith((message) => updates(message as RepeatedFieldOrder)) as RepeatedFieldOrder; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RepeatedFieldOrder create() => RepeatedFieldOrder._(); + RepeatedFieldOrder createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RepeatedFieldOrder getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedFieldOrder? _defaultInstance; + + @$pb.TagNumber(1) + $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') + ..aOM(6, 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, + 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 (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) + AnyData get typeOptions => $_getN(5); + @$pb.TagNumber(6) + set typeOptions(AnyData v) { setField(6, v); } + @$pb.TagNumber(6) + $core.bool hasTypeOptions() => $_has(5); + @$pb.TagNumber(6) + void clearTypeOptions() => clearField(6); + @$pb.TagNumber(6) + AnyData ensureTypeOptions() => $_ensure(5); +} + +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') ? '' : 'typeUrl') + ..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? typeUrl, + $core.List<$core.int>? value, + }) { + final _result = create(); + if (typeUrl != null) { + _result.typeUrl = typeUrl; + } + 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 typeUrl => $_getSZ(0); + @$pb.TagNumber(1) + set typeUrl($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasTypeUrl() => $_has(0); + @$pb.TagNumber(1) + void clearTypeUrl() => 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') + ..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); + factory RowOrder.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') + RowOrder clone() => RowOrder()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RowOrder copyWith(void Function(RowOrder) updates) => super.copyWith((message) => updates(message as RowOrder)) as RowOrder; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RowOrder create() => RowOrder._(); + RowOrder createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RowOrder getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RowOrder? _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 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); +} + +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); +} + +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') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aInt64(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'modifiedTime') + ..m<$core.String, Cell>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'Row.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: Cell.create) + ..hasRequiredFields = false + ; + + Row._() : super(); + factory Row({ + $core.String? id, + $core.String? gridId, + $fixnum.Int64? modifiedTime, + $core.Map<$core.String, Cell>? cellByFieldId, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (gridId != null) { + _result.gridId = gridId; + } + if (modifiedTime != null) { + _result.modifiedTime = modifiedTime; + } + if (cellByFieldId != null) { + _result.cellByFieldId.addAll(cellByFieldId); + } + return _result; + } + factory Row.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Row.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') + Row clone() => Row()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Row copyWith(void Function(Row) updates) => super.copyWith((message) => updates(message as Row)) as Row; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Row create() => Row._(); + Row createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Row getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Row? _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) + $fixnum.Int64 get modifiedTime => $_getI64(2); + @$pb.TagNumber(3) + set modifiedTime($fixnum.Int64 v) { $_setInt64(2, v); } + @$pb.TagNumber(3) + $core.bool hasModifiedTime() => $_has(2); + @$pb.TagNumber(3) + void clearModifiedTime() => clearField(3); + + @$pb.TagNumber(4) + $core.Map<$core.String, Cell> get cellByFieldId => $_getMap(3); +} + +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') ? '' : '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) + ..hasRequiredFields = false + ; + + Cell._() : super(); + factory Cell({ + $core.String? id, + $core.String? rowId, + $core.String? fieldId, + AnyData? 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 Cell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Cell.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') + Cell clone() => Cell()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Cell copyWith(void Function(Cell) updates) => super.copyWith((message) => updates(message as Cell)) as Cell; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Cell create() => Cell._(); + Cell createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Cell getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Cell? _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); +} + +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') + ..hasRequiredFields = false + ; + + CreateGridPayload._() : super(); + factory CreateGridPayload({ + $core.String? name, + }) { + final _result = create(); + if (name != null) { + _result.name = name; + } + return _result; + } + factory CreateGridPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CreateGridPayload.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') + CreateGridPayload clone() => CreateGridPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CreateGridPayload copyWith(void Function(CreateGridPayload) updates) => super.copyWith((message) => updates(message as CreateGridPayload)) as CreateGridPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CreateGridPayload create() => CreateGridPayload._(); + CreateGridPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CreateGridPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CreateGridPayload? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get name => $_getSZ(0); + @$pb.TagNumber(1) + set name($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasName() => $_has(0); + @$pb.TagNumber(1) + void clearName() => clearField(1); +} + +class GridId extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridId', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value') + ..hasRequiredFields = false + ; + + GridId._() : super(); + factory GridId({ + $core.String? value, + }) { + final _result = create(); + if (value != null) { + _result.value = value; + } + return _result; + } + factory GridId.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridId.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') + GridId clone() => GridId()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GridId copyWith(void Function(GridId) updates) => super.copyWith((message) => updates(message as GridId)) as GridId; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static GridId create() => GridId._(); + GridId createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GridId getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridId? _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-grid-data-model/grid.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart new file mode 100644 index 0000000000..661b26532c --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart @@ -0,0 +1,34 @@ +/// +// Generated code. Do not modify. +// source: grid.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/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart new file mode 100644 index 0000000000..dfe0be5c29 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -0,0 +1,187 @@ +/// +// Generated code. Do not modify. +// source: grid.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 gridDescriptor instead') +const Grid$json = const { + '1': 'Grid', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'filters', '3': 2, '4': 1, '5': 11, '6': '.RepeatedGridFilter', '10': 'filters'}, + const {'1': 'field_orders', '3': 3, '4': 1, '5': 11, '6': '.RepeatedFieldOrder', '10': 'fieldOrders'}, + const {'1': 'row_orders', '3': 4, '4': 1, '5': 11, '6': '.RepeatedRowOrder', '10': 'rowOrders'}, + ], +}; + +/// Descriptor for `Grid`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBItCgdmaWx0ZXJzGAIgASgLMhMuUmVwZWF0ZWRHcmlkRmlsdGVyUgdmaWx0ZXJzEjYKDGZpZWxkX29yZGVycxgDIAEoCzITLlJlcGVhdGVkRmllbGRPcmRlclILZmllbGRPcmRlcnMSMAoKcm93X29yZGVycxgEIAEoCzIRLlJlcGVhdGVkUm93T3JkZXJSCXJvd09yZGVycw=='); +@$core.Deprecated('Use gridFilterDescriptor instead') +const GridFilter$json = const { + '1': 'GridFilter', + '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'}, + ], +}; + +/// Descriptor for `GridFilter`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridFilterDescriptor = $convert.base64Decode('CgpHcmlkRmlsdGVyEg4KAmlkGAEgASgJUgJpZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2M='); +@$core.Deprecated('Use repeatedGridFilterDescriptor instead') +const RepeatedGridFilter$json = const { + '1': 'RepeatedGridFilter', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.GridFilter', '10': 'items'}, + ], +}; + +/// Descriptor for `RepeatedGridFilter`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedGridFilterDescriptor = $convert.base64Decode('ChJSZXBlYXRlZEdyaWRGaWx0ZXISIQoFaXRlbXMYASADKAsyCy5HcmlkRmlsdGVyUgVpdGVtcw=='); +@$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'}, + const {'1': 'width', '3': 3, '4': 1, '5': 5, '10': 'width'}, + ], +}; + +/// Descriptor for `FieldOrder`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEh4KCnZpc2liaWxpdHkYAiABKAhSCnZpc2liaWxpdHkSFAoFd2lkdGgYAyABKAVSBXdpZHRo'); +@$core.Deprecated('Use repeatedFieldOrderDescriptor instead') +const RepeatedFieldOrder$json = const { + '1': 'RepeatedFieldOrder', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.FieldOrder', '10': 'items'}, + ], +}; + +/// 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': 'type_options', '3': 6, '4': 1, '5': 11, '6': '.AnyData', '10': 'typeOptions'}, + ], +}; + +/// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIrCgx0eXBlX29wdGlvbnMYBiABKAsyCC5BbnlEYXRhUgt0eXBlT3B0aW9ucw=='); +@$core.Deprecated('Use anyDataDescriptor instead') +const AnyData$json = const { + '1': 'AnyData', + '2': const [ + const {'1': 'type_url', '3': 1, '4': 1, '5': 9, '10': 'typeUrl'}, + 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('CgdBbnlEYXRhEhkKCHR5cGVfdXJsGAEgASgJUgd0eXBlVXJsEhQKBXZhbHVlGAIgASgMUgV2YWx1ZQ=='); +@$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'}, + ], +}; + +/// Descriptor for `RowOrder`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List rowOrderDescriptor = $convert.base64Decode('CghSb3dPcmRlchIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIeCgp2aXNpYmlsaXR5GAMgASgIUgp2aXNpYmlsaXR5'); +@$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'); +@$core.Deprecated('Use rowDescriptor instead') +const Row$json = const { + '1': 'Row', + '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': 'modified_time', '3': 3, '4': 1, '5': 3, '10': 'modifiedTime'}, + const {'1': 'cell_by_field_id', '3': 4, '4': 3, '5': 11, '6': '.Row.CellByFieldIdEntry', '10': 'cellByFieldId'}, + ], + '3': const [Row_CellByFieldIdEntry$json], +}; + +@$core.Deprecated('Use rowDescriptor instead') +const Row_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': '.Cell', '10': 'value'}, + ], + '7': const {'7': true}, +}; + +/// Descriptor for `Row`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List rowDescriptor = $convert.base64Decode('CgNSb3cSDgoCaWQYASABKAlSAmlkEhcKB2dyaWRfaWQYAiABKAlSBmdyaWRJZBIjCg1tb2RpZmllZF90aW1lGAMgASgDUgxtb2RpZmllZFRpbWUSQAoQY2VsbF9ieV9maWVsZF9pZBgEIAMoCzIXLlJvdy5DZWxsQnlGaWVsZElkRW50cnlSDWNlbGxCeUZpZWxkSWQaRwoSQ2VsbEJ5RmllbGRJZEVudHJ5EhAKA2tleRgBIAEoCVIDa2V5EhsKBXZhbHVlGAIgASgLMgUuQ2VsbFIFdmFsdWU6AjgB'); +@$core.Deprecated('Use cellDescriptor instead') +const Cell$json = const { + '1': 'Cell', + '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'}, + ], +}; + +/// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhwKBGRhdGEYBCABKAsyCC5BbnlEYXRhUgRkYXRh'); +@$core.Deprecated('Use createGridPayloadDescriptor instead') +const CreateGridPayload$json = const { + '1': 'CreateGridPayload', + '2': const [ + const {'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'}, + ], +}; + +/// Descriptor for `CreateGridPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List createGridPayloadDescriptor = $convert.base64Decode('ChFDcmVhdGVHcmlkUGF5bG9hZBISCgRuYW1lGAEgASgJUgRuYW1l'); +@$core.Deprecated('Use gridIdDescriptor instead') +const GridId$json = const { + '1': 'GridId', + '2': const [ + const {'1': 'value', '3': 1, '4': 1, '5': 9, '10': 'value'}, + ], +}; + +/// Descriptor for `GridId`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridIdDescriptor = $convert.base64Decode('CgZHcmlkSWQSFAoFdmFsdWUYASABKAlSBXZhbHVl'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbserver.dart new file mode 100644 index 0000000000..1ea5bad0ba --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: grid.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 'grid.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 new file mode 100644 index 0000000000..3f0100c8d6 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart @@ -0,0 +1,2 @@ +// Auto-generated, do not edit +export './grid.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pb.dart new file mode 100644 index 0000000000..5bfad20674 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pb.dart @@ -0,0 +1,11 @@ +/// +// Generated code. Do not modify. +// source: event_map.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 'event_map.pbenum.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 new file mode 100644 index 0000000000..c8b9528369 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart @@ -0,0 +1,26 @@ +/// +// Generated code. Do not modify. +// source: event_map.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 GridEvent extends $pb.ProtobufEnum { + static const GridEvent CreateGrid = GridEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateGrid'); + static const GridEvent OpenGrid = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'OpenGrid'); + + static const $core.List values = [ + CreateGrid, + OpenGrid, + ]; + + static final $core.Map<$core.int, GridEvent> _byValue = $pb.ProtobufEnum.initByValue(values); + static GridEvent? valueOf($core.int value) => _byValue[value]; + + const GridEvent._($core.int v, $core.String n) : super(v, n); +} + 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 new file mode 100644 index 0000000000..1b16f0b657 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart @@ -0,0 +1,21 @@ +/// +// Generated code. Do not modify. +// source: event_map.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 gridEventDescriptor instead') +const GridEvent$json = const { + '1': 'GridEvent', + '2': const [ + const {'1': 'CreateGrid', '2': 0}, + const {'1': 'OpenGrid', '2': 1}, + ], +}; + +/// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDgoKQ3JlYXRlR3JpZBAAEgwKCE9wZW5HcmlkEAE='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbserver.dart new file mode 100644 index 0000000000..e359d1146c --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: event_map.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 'event_map.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 new file mode 100644 index 0000000000..a5735f1a1a --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart @@ -0,0 +1,2 @@ +// Auto-generated, do not edit +export './event_map.pb.dart'; diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index b0eec95054..dec40ba22d 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1041,6 +1041,27 @@ dependencies = [ [[package]] name = "flowy-grid" version = "0.1.0" +dependencies = [ + "flowy-derive", + "flowy-error", + "flowy-grid-data-model", + "lib-dispatch", + "lib-infra", + "protobuf", + "strum", + "strum_macros", + "tracing", +] + +[[package]] +name = "flowy-grid-data-model" +version = "0.1.0" +dependencies = [ + "bytes", + "flowy-derive", + "lib-infra", + "protobuf", +] [[package]] name = "flowy-net" @@ -1091,6 +1112,7 @@ dependencies = [ "flowy-collaboration", "flowy-database", "flowy-folder", + "flowy-grid", "flowy-net", "flowy-sync", "flowy-user", diff --git a/frontend/rust-lib/flowy-folder/Cargo.toml b/frontend/rust-lib/flowy-folder/Cargo.toml index 45f7ffb3e7..57e659ddd1 100644 --- a/frontend/rust-lib/flowy-folder/Cargo.toml +++ b/frontend/rust-lib/flowy-folder/Cargo.toml @@ -49,11 +49,11 @@ serde_json = "1.0" flowy-folder = { path = "../flowy-folder", features = ["flowy_unit_test"]} flowy-test = { path = "../flowy-test" } +[build-dependencies] +lib-infra = { path = "../../../shared-lib/lib-infra", features = ["protobuf_file_gen", "proto_gen"] } + [features] default = [] http_server = [] flowy_unit_test = ["lib-ot/flowy_unit_test", "flowy-sync/flowy_unit_test"] -dart = ["lib-infra/dart", "flowy-folder/dart", "flowy-folder/dart",] - -[build-dependencies] -lib-infra = { path = "../../../shared-lib/lib-infra", features = ["protobuf_file_gen", "proto_gen"] } \ No newline at end of file +dart = ["lib-infra/dart", "flowy-folder/dart"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index 6043e37a69..b2d58b7794 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -6,3 +6,20 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +flowy-grid-data-model = { path = "../../../shared-lib/flowy-grid-data-model" } +lib-dispatch = { path = "../lib-dispatch" } +lib-infra = { path = "../../../shared-lib/lib-infra" } +flowy-error = { path = "../flowy-error"} +strum = "0.21" +strum_macros = "0.21" +flowy-derive = { path = "../../../shared-lib/flowy-derive" } +tracing = { version = "0.1", features = ["log"] } +protobuf = {version = "2.18.0"} + +[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 diff --git a/frontend/rust-lib/flowy-grid/Flowy.toml b/frontend/rust-lib/flowy-grid/Flowy.toml new file mode 100644 index 0000000000..934d557323 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/Flowy.toml @@ -0,0 +1,3 @@ + +proto_crates = ["src/event_map.rs"] +event_files = ["src/event_map.rs"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/build.rs b/frontend/rust-lib/flowy-grid/build.rs new file mode 100644 index 0000000000..4ab7b9e23d --- /dev/null +++ b/frontend/rust-lib/flowy-grid/build.rs @@ -0,0 +1,7 @@ +use lib_infra::code_gen; + +fn main() { + let crate_name = env!("CARGO_PKG_NAME"); + code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto"); + code_gen::dart_event::gen(crate_name); +} diff --git a/frontend/rust-lib/flowy-grid/src/controller.rs b/frontend/rust-lib/flowy-grid/src/controller.rs new file mode 100644 index 0000000000..acbe116978 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/controller.rs @@ -0,0 +1 @@ +pub struct GridManager {} diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs new file mode 100644 index 0000000000..0d7b0a9f90 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -0,0 +1,23 @@ +use crate::controller::GridManager; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{CreateGridPayload, Grid, GridId}; +use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; +use std::sync::Arc; + +#[tracing::instrument(skip(data, controller), err)] +pub(crate) async fn create_grid_handler( + data: Data, + controller: AppData>, +) -> DataResult { + todo!() +} + +#[tracing::instrument(skip(data, controller), err)] +pub(crate) async fn open_grid_handler( + data: Data, + controller: AppData>, +) -> DataResult { + let params: GridId = data.into_inner(); + + todo!() +} diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs new file mode 100644 index 0000000000..b1caa3993f --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -0,0 +1,26 @@ +use crate::controller::GridManager; +use crate::event_handler::*; +use flowy_derive::{Flowy_Event, ProtoBuf_Enum}; +use lib_dispatch::prelude::*; +use std::sync::Arc; +use strum_macros::Display; + +pub fn create(grid_manager: Arc) -> Module { + let mut module = Module::new().name(env!("CARGO_PKG_NAME")).data(grid_manager); + + module = module + .event(GridEvent::CreateGrid, create_grid_handler) + .event(GridEvent::OpenGrid, open_grid_handler); + + module +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] +#[event_err = "FlowyError"] +pub enum GridEvent { + #[event(input = "CreateGridPayload", output = "Grid")] + CreateGrid = 0, + + #[event(input = "GridId", output = "Grid")] + OpenGrid = 1, +} diff --git a/frontend/rust-lib/flowy-grid/src/lib.rs b/frontend/rust-lib/flowy-grid/src/lib.rs index 1b4a90c938..65726c3dbd 100644 --- a/frontend/rust-lib/flowy-grid/src/lib.rs +++ b/frontend/rust-lib/flowy-grid/src/lib.rs @@ -1,8 +1,5 @@ -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - let result = 2 + 2; - assert_eq!(result, 4); - } -} +mod controller; +mod event_handler; +mod event_map; + +mod protobuf; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/mod.rs b/frontend/rust-lib/flowy-grid/src/protobuf/mod.rs new file mode 100644 index 0000000000..da97aad28a --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/mod.rs @@ -0,0 +1,4 @@ +#![cfg_attr(rustfmt, rustfmt::skip)] +// Auto-generated, do not edit +mod model; +pub use model::*; \ No newline at end of file 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 new file mode 100644 index 0000000000..d4c95c928b --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs @@ -0,0 +1,91 @@ +// 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 `event_map.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 GridEvent { + CreateGrid = 0, + OpenGrid = 1, +} + +impl ::protobuf::ProtobufEnum for GridEvent { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(GridEvent::CreateGrid), + 1 => ::std::option::Option::Some(GridEvent::OpenGrid), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [GridEvent] = &[ + GridEvent::CreateGrid, + GridEvent::OpenGrid, + ]; + 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::("GridEvent", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for GridEvent { +} + +impl ::std::default::Default for GridEvent { + fn default() -> Self { + GridEvent::CreateGrid + } +} + +impl ::protobuf::reflect::ProtobufValue for GridEvent { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x0fevent_map.proto*)\n\tGridEvent\x12\x0e\n\nCreateGrid\x10\0\x12\x0c\ + \n\x08OpenGrid\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 new file mode 100644 index 0000000000..56c0b3d949 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs @@ -0,0 +1,5 @@ +#![cfg_attr(rustfmt, rustfmt::skip)] +// Auto-generated, do not edit + +mod event_map; +pub use event_map::*; 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 new file mode 100644 index 0000000000..f1a860aee0 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +enum GridEvent { + CreateGrid = 0; + OpenGrid = 1; +} diff --git a/frontend/rust-lib/flowy-sdk/Cargo.toml b/frontend/rust-lib/flowy-sdk/Cargo.toml index d7dcd58789..5f0de22ecd 100644 --- a/frontend/rust-lib/flowy-sdk/Cargo.toml +++ b/frontend/rust-lib/flowy-sdk/Cargo.toml @@ -11,6 +11,7 @@ lib-log = { path = "../lib-log" } 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-database = { path = "../flowy-database" } flowy-block = { path = "../flowy-block" } flowy-sync = { path = "../flowy-sync" } @@ -39,4 +40,4 @@ futures-util = "0.3.15" [features] http_server = ["flowy-user/http_server", "flowy-folder/http_server", "flowy-block/http_server"] use_bunyan = ["lib-log/use_bunyan"] -dart = ["flowy-user/dart", "flowy-net/dart", "flowy-folder/dart", "flowy-collaboration/dart"] +dart = ["flowy-user/dart", "flowy-net/dart", "flowy-folder/dart", "flowy-collaboration/dart", "flowy-grid/dart"] 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 3e25199227..092fcbd3db 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -146,3 +146,15 @@ pub struct Cell { #[pb(index = 4)] pub data: AnyData, } + +#[derive(ProtoBuf, Default)] +pub struct CreateGridPayload { + #[pb(index = 1)] + pub name: String, +} + +#[derive(Clone, ProtoBuf, Default, Debug)] +pub struct GridId { + #[pb(index = 1)] + pub value: 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 77db4ecdb1..127bdfbeb8 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 @@ -2699,6 +2699,324 @@ impl ::protobuf::reflect::ProtobufValue for Cell { } } +#[derive(PartialEq,Clone,Default)] +pub struct CreateGridPayload { + // message fields + pub name: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CreateGridPayload { + fn default() -> &'a CreateGridPayload { + ::default_instance() + } +} + +impl CreateGridPayload { + pub fn new() -> CreateGridPayload { + ::std::default::Default::default() + } + + // string name = 1; + + + 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 CreateGridPayload { + 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.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.name.is_empty() { + my_size += ::protobuf::rt::string_size(1, &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.name.is_empty() { + os.write_string(1, &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() -> CreateGridPayload { + CreateGridPayload::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>( + "name", + |m: &CreateGridPayload| { &m.name }, + |m: &mut CreateGridPayload| { &mut m.name }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CreateGridPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CreateGridPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CreateGridPayload::new) + } +} + +impl ::protobuf::Clear for CreateGridPayload { + fn clear(&mut self) { + self.name.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CreateGridPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CreateGridPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct GridId { + // 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 GridId { + fn default() -> &'a GridId { + ::default_instance() + } +} + +impl GridId { + pub fn new() -> GridId { + ::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 GridId { + 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() -> GridId { + GridId::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: &GridId| { &m.value }, + |m: &mut GridId| { &mut m.value }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridId", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static GridId { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridId::new) + } +} + +impl ::protobuf::Clear for GridId { + fn clear(&mut self) { + self.value.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for GridId { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GridId { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum FieldType { RichText = 0, @@ -2792,8 +3110,10 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x0b2\x05.CellR\x05value:\x028\x01\"f\n\x04Cell\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*d\n\tFieldType\x12\x0c\n\x08Rich\ - Text\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\ + \x04\x20\x01(\x0b2\x08.AnyDataR\x04data\"'\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*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\ "; 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 c4947247a9..012f53aaab 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 @@ -54,6 +54,12 @@ message Cell { string field_id = 3; AnyData data = 4; } +message CreateGridPayload { + string name = 1; +} +message GridId { + string value = 1; +} enum FieldType { RichText = 0; Number = 1; From 0bbf17f776709a8f46fdcf5f6cef4e5fafe0edb2 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 3 Mar 2022 10:51:52 +0800 Subject: [PATCH 05/17] feat: add grid widget --- .../workspace/application/grid/grid_bloc.dart | 135 +++++ .../application/grid/grid_service.dart | 20 + .../controller/flowy_table_selection.dart | 73 +++ .../plugins/grid/controller/grid_scroll.dart | 22 + .../plugins/grid/grid_layout.dart | 17 + .../presentation/plugins/grid/grid_page.dart | 150 ++++++ .../presentation/plugins/grid/grid_sizes.dart | 16 + .../widgets/grid_content/cell_builder.dart | 17 + .../widgets/grid_content/cell_container.dart | 34 ++ .../widgets/grid_content/cell_decoration.dart | 10 + .../grid/widgets/grid_content/grid_cell.dart | 68 +++ .../grid/widgets/grid_content/grid_row.dart | 64 +++ .../plugins/grid/widgets/grid_error_page.dart | 14 + .../grid/widgets/grid_footer/grid_footer.dart | 46 ++ .../grid/widgets/grid_header/constants.dart | 5 + .../grid/widgets/grid_header/header.dart | 0 .../grid/widgets/grid_header/header_cell.dart | 52 ++ .../flowy_sdk/lib/dispatch/dispatch.dart | 3 + .../flowy-grid-data-model/grid.pb.dart | 138 ++++- .../flowy-grid-data-model/grid.pbjson.dart | 25 +- .../src/entities/grid.rs | 17 +- .../src/protobuf/model/grid.rs | 492 +++++++++++++++--- .../src/protobuf/proto/grid.proto | 9 +- 23 files changed, 1343 insertions(+), 84 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart create mode 100644 frontend/app_flowy/lib/workspace/application/grid/grid_service.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/controller/flowy_table_selection.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/controller/grid_scroll.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_layout.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_page.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_sizes.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_builder.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_container.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_decoration.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_cell.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_row.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_error_page.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_footer/grid_footer.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/constants.dart create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header.dart create mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header_cell.dart diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart new file mode 100644 index 0000000000..e6663c4515 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -0,0 +1,135 @@ +import 'dart:async'; + +import 'package:dartz/dartz.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 'grid_service.dart'; + +part 'grid_bloc.freezed.dart'; + +class GridBloc extends Bloc { + final GridService service; + final View view; + late Grid _grid; + + GridBloc({required this.view, required this.service}) : super(GridState.initial()) { + on( + (event, emit) async { + await event.map( + initial: (Initial value) async { + await _initial(value, emit); + }, + createRow: (_CreateRow value) { + service.createRow(gridId: view.id); + }, + delete: (_Delete value) {}, + rename: (_Rename value) {}, + updateDesc: (_Desc value) {}, + ); + }, + ); + } + + @override + Future close() async { + return super.close(); + } + + Future _initial(Initial value, Emitter emit) async { + final result = await service.openGrid(gridId: view.id); + result.fold( + (grid) { + _grid = grid; + _loadGridInfo(emit); + }, + (err) { + emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))); + }, + ); + } + + Future _loadGridInfo(Emitter emit) async { + emit( + state.copyWith(loadingState: GridLoadingState.finish(left(unit))), + ); + } +} + +@freezed +abstract class GridEvent with _$GridEvent { + const factory GridEvent.initial() = Initial; + 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; + const factory GridEvent.createRow() = _CreateRow; +} + +@freezed +abstract class GridState with _$GridState { + const factory GridState({ + required GridLoadingState loadingState, + required Option> gridInfo, + }) = _GridState; + + factory GridState.initial() => GridState( + loadingState: const _Loading(), + gridInfo: none(), + ); +} + +@freezed +class GridLoadingState with _$GridLoadingState { + const factory GridLoadingState.loading() = _Loading; + const factory GridLoadingState.finish(Either successOrFail) = _Finish; +} + +typedef FieldById = Map; +typedef RowById = Map; +typedef CellById = Map; + +class GridInfo { + List rowOrders; + List fieldOrders; + RowById rowMap; + FieldById fieldMap; + + GridInfo({ + required this.rowOrders, + required this.fieldOrders, + required this.fieldMap, + required this.rowMap, + }); + + RowInfo rowInfoAtIndex(int index) { + final rowOrder = rowOrders[index]; + final Row row = rowMap[rowOrder.rowId]!; + final cellMap = row.cellByFieldId; + + final displayCellMap = {}; + + return RowInfo( + fieldOrders: fieldOrders, + fieldMap: fieldMap, + displayCellMap: displayCellMap, + ); + } + + int numberOfRows() { + return rowOrders.length; + } +} + +class RowInfo { + List fieldOrders; + FieldById fieldMap; + CellById displayCellMap; + RowInfo({ + required this.fieldOrders, + required this.fieldMap, + required this.displayCellMap, + }); +} diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart new file mode 100644 index 0000000000..b69e4a8e5a --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -0,0 +1,20 @@ +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 'package:dartz/dartz.dart'; + +class GridService { + Future> createGrid({required String name}) { + final payload = CreateGridPayload()..name = name; + return GridEventCreateGrid(payload).send(); + } + + Future> openGrid({required String gridId}) { + final payload = GridId(value: gridId); + return GridEventOpenGrid(payload).send(); + } + + Future> createRow({required String gridId}) { + throw UnimplementedError(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/controller/flowy_table_selection.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/controller/flowy_table_selection.dart new file mode 100755 index 0000000000..7f01b7dcf0 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/controller/flowy_table_selection.dart @@ -0,0 +1,73 @@ +/// The data structor representing each selection of flowy table. +enum FlowyTableSelectionType { + item, + row, + col, +} + +class FlowyTableSelectionItem { + final FlowyTableSelectionType type; + final int? row; + final int? column; + + const FlowyTableSelectionItem({ + required this.type, + this.row, + this.column, + }); + + @override + String toString() { + return '$type($row, $column)'; + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) { + return true; + } + return other is FlowyTableSelectionItem && + type == other.type && + row == other.row && + column == other.column; + } + + @override + int get hashCode => type.hashCode ^ row.hashCode ^ column.hashCode; +} + +class FlowyTableSelection { + Set _items = {}; + + Set get items => _items; + + FlowyTableSelection( + this._items, + ); + + FlowyTableSelection.combine( + FlowyTableSelection lhs, FlowyTableSelection rhs) { + this..combine(lhs)..combine(rhs); + } + + FlowyTableSelection operator +(FlowyTableSelection other) { + return this..combine(other); + } + + void combine(FlowyTableSelection other) { + var totalItems = items..union(other.items); + final rows = totalItems + .where((ele) => ele.type == FlowyTableSelectionType.row) + .map((e) => e.row) + .toSet(); + final cols = totalItems + .where((ele) => ele.type == FlowyTableSelectionType.col) + .map((e) => e.column) + .toSet(); + totalItems.removeWhere((ele) { + return ele.type == FlowyTableSelectionType.item && + (rows.contains(ele.row) || cols.contains(ele.column)); + }); + _items = totalItems; + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/controller/grid_scroll.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/controller/grid_scroll.dart new file mode 100755 index 0000000000..213b16cfae --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/controller/grid_scroll.dart @@ -0,0 +1,22 @@ +import 'package:flutter/material.dart'; + +class GridScrollController { + final ScrollController _verticalController = ScrollController(); + final ScrollController _horizontalController = ScrollController(); + + ScrollController get verticalController => _verticalController; + ScrollController get horizontalController => _horizontalController; + + GridScrollController(); + + // final SelectionChangeCallback? onSelectionChanged; + + // final ShouldApplySelection? shouldApplySelection; + + // final ScrollCallback? onScroll; + + void dispose() { + verticalController.dispose(); + horizontalController.dispose(); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_layout.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_layout.dart new file mode 100755 index 0000000000..df2b73cb12 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_layout.dart @@ -0,0 +1,17 @@ +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; + +import 'grid_sizes.dart'; + +class GridLayout { + static double headerWidth(List fieldOrders) { + if (fieldOrders.isEmpty) return 0; + + final fieldsWidth = fieldOrders + .map( + (fieldOrder) => fieldOrder.width.toDouble(), + ) + .reduce((value, element) => value + element); + + return fieldsWidth + GridSize.firstHeaderPadding; + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_page.dart new file mode 100755 index 0000000000..1eb102f7bb --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_page.dart @@ -0,0 +1,150 @@ +import 'package:app_flowy/startup/startup.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'; +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:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter/material.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/controller/grid_scroll.dart'; +import 'package:styled_widget/styled_widget.dart'; + +import 'grid_layout.dart'; +import 'grid_sizes.dart'; +import 'widgets/grid_content/grid_row.dart'; +import 'widgets/grid_footer/grid_footer.dart'; +import 'widgets/grid_header/header.dart'; + +class GridPage extends StatefulWidget { + final View view; + + GridPage({Key? key, required this.view}) : super(key: ValueKey(view.id)); + + @override + State createState() => _GridPageState(); +} + +class _GridPageState extends State { + @override + Widget build(BuildContext context) { + return MultiBlocProvider( + providers: [ + BlocProvider(create: (context) => getIt()), + ], + child: BlocBuilder( + builder: (context, state) { + return state.loadingState.map( + loading: (_) => const Center(child: CircularProgressIndicator.adaptive()), + finish: (result) => result.successOrFail.fold( + (_) => const GridBody(), + (err) => FlowyErrorPage(err.toString()), + ), + ); + }, + ), + ); + } + + @override + void dispose() { + super.dispose(); + } + + @override + void deactivate() { + super.deactivate(); + } + + @override + void didUpdateWidget(covariant GridPage oldWidget) { + super.didUpdateWidget(oldWidget); + } +} + +class GridBody extends StatefulWidget { + const GridBody({Key? key}) : super(key: key); + + @override + _GridBodyState createState() => _GridBodyState(); +} + +class _GridBodyState extends State { + final _scrollController = GridScrollController(); + + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + return state.gridInfo.fold( + () => const Center(child: CircularProgressIndicator.adaptive()), + (some) => some.fold( + (gridInfo) => _renderGrid(context, gridInfo), + (err) => FlowyErrorPage(err.toString()), + ), + ); + }, + ); + } + + Widget _renderGrid(BuildContext context, GridInfo gridInfo) { + return Stack( + children: [ + StyledSingleChildScrollView( + controller: _scrollController.horizontalController, + axis: Axis.horizontal, + child: SizedBox( + width: GridLayout.headerWidth(gridInfo.fieldOrders), + child: CustomScrollView( + physics: StyledScrollPhysics(), + controller: _scrollController.verticalController, + slivers: [ + _buildHeader(gridInfo.fieldOrders, gridInfo.fieldMap), + _buildRows(gridInfo), + _builderFooter(context), + ], + ), + ), + ), + ScrollbarListStack( + axis: Axis.vertical, + controller: _scrollController.verticalController, + barSize: GridSize.scrollBarSize, + child: Container(), + ).padding(right: 0, top: GridSize.headerHeight, bottom: GridSize.scrollBarSize), + ], + ); + } + + Widget _buildHeader(List fieldOrders, FieldById fieldById) { + return SliverPersistentHeader( + delegate: GridHeaderDelegate(fieldOrders, fieldById), + floating: true, + pinned: true, + ); + } + + Widget _buildRows(GridInfo gridInfo) { + return SliverList( + delegate: SliverChildBuilderDelegate((context, index) { + final rowInfo = gridInfo.rowInfoAtIndex(index); + return RepaintBoundary(child: GridRow(rowInfo)); + }, childCount: gridInfo.numberOfRows()), + ); + } + + Widget _builderFooter(BuildContext context) { + return GridFooter( + onAddRow: () { + context.read().add(const GridEvent.createRow()); + }, + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_sizes.dart new file mode 100755 index 0000000000..e833df5cc4 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_sizes.dart @@ -0,0 +1,16 @@ +class GridInsets { + static double scale = 1; + + static double get horizontal => 6 * scale; + static double get vertical => 6 * scale; +} + +class GridSize { + static double scale = 1; + + static double get scrollBarSize => 12 * scale; + static double get headerHeight => 50 * scale; + static double get rowHeight => 50 * scale; + static double get footerHeight => 40 * scale; + static double get firstHeaderPadding => 20 * scale; +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_builder.dart new file mode 100755 index 0000000000..a4cab931c9 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_builder.dart @@ -0,0 +1,17 @@ +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'grid_cell.dart'; + +class GridCellBuilder { + static GridCell buildCell(Field? field, DisplayCell? cell) { + if (field == null || cell == null) { + return BlankCell(); + } + + switch (field.fieldType) { + case FieldType.RichText: + return GridTextCell(cell.content); + default: + return BlankCell(); + } + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_container.dart new file mode 100755 index 0000000000..c769a60d34 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_container.dart @@ -0,0 +1,34 @@ +import 'package:app_flowy/workspace/presentation/plugins/grid/grid_sizes.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'; +import 'grid_cell.dart'; + +class CellContainer extends StatelessWidget { + final GridCell child; + final double width; + 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, + ), + ), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_decoration.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_decoration.dart new file mode 100755 index 0000000000..0e74073e14 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_decoration.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +class CellDecoration { + static BoxDecoration box({required Color color}) { + return BoxDecoration( + border: Border.all(color: Colors.black26, width: 0.2), + color: color, + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_cell.dart new file mode 100755 index 0000000000..a23259c8c3 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_cell.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; +// ignore: import_of_legacy_library_into_null_safe + +/// The interface of base cell. +abstract class GridCell extends StatelessWidget { + final canSelect = true; + + const GridCell({Key? key}) : super(key: key); +} + +class GridTextCell extends GridCell { + final String content; + const GridTextCell(this.content, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Text(content); + } +} + +class DateCell extends GridCell { + final String content; + const DateCell(this.content, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Text(content); + } +} + +class NumberCell extends GridCell { + final String content; + const NumberCell(this.content, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Text(content); + } +} + +class SingleSelectCell extends GridCell { + final String content; + const SingleSelectCell(this.content, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Text(content); + } +} + +class MultiSelectCell extends GridCell { + final String content; + const MultiSelectCell(this.content, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Text(content); + } +} + +class BlankCell extends GridCell { + 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/widgets/grid_content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_row.dart new file mode 100755 index 0000000000..8a1202197e --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_row.dart @@ -0,0 +1,64 @@ +import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/grid_sizes.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; +import 'package:flutter/material.dart'; +import 'cell_builder.dart'; +import 'cell_container.dart'; +import 'grid_row_leading.dart'; + +class GridRowContext { + final RepeatedFieldOrder fieldOrders; + final Map fieldById; + final Map cellByFieldId; + GridRowContext(this.fieldOrders, this.fieldById, this.cellByFieldId); +} + +class GridRow extends StatelessWidget { + final RowInfo rowInfo; + final Function(bool)? onHoverChange; + const GridRow(this.rowInfo, {Key? key, this.onHoverChange}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: GridSize.rowHeight, + child: _buildRowBody(), + ); + } + + 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()); + + rowInfo.fieldOrders.where((element) => element.visibility).forEach((fieldOrder) { + final field = rowInfo.fieldMap[fieldOrder.fieldId]; + final data = rowInfo.displayCellMap[fieldOrder.fieldId]; + + final cell = CellContainer( + width: fieldOrder.width.toDouble(), + child: GridCellBuilder.buildCell(field, data), + ); + + cells.add(cell); + }); + return cells; + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_error_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_error_page.dart new file mode 100755 index 0000000000..92973a05b3 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_error_page.dart @@ -0,0 +1,14 @@ +import 'package:flutter/material.dart'; + +class GridUnknownError extends StatelessWidget { + const GridUnknownError({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + child: Center( + child: CircularProgressIndicator(), + ), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_footer/grid_footer.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_footer/grid_footer.dart new file mode 100755 index 0000000000..b5ccee4892 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_footer/grid_footer.dart @@ -0,0 +1,46 @@ +import 'package:app_flowy/workspace/presentation/plugins/grid/grid_sizes.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/widgets/grid_content/cell_decoration.dart'; +import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; +import 'package:flutter/material.dart'; + +class GridFooter extends StatelessWidget { + final VoidCallback? onAddRow; + const GridFooter({Key? key, required this.onAddRow}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SliverToBoxAdapter( + child: SizedBox( + height: GridSize.footerHeight, + child: Row( + children: [ + AddRowButton(onTap: onAddRow), + ], + ), + ), + ); + } +} + +class AddRowButton extends StatelessWidget { + final VoidCallback? onTap; + const AddRowButton({Key? key, required this.onTap}) : super(key: key); + + @override + Widget build(BuildContext context) { + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: onTap, + child: MouseHoverBuilder( + builder: (_, isHovered) => Container( + width: GridSize.firstHeaderPadding, + height: GridSize.footerHeight, + decoration: CellDecoration.box( + color: isHovered ? Colors.red.withOpacity(.1) : Colors.white, + ), + child: const Icon(Icons.add, size: 16), + ), + ), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/constants.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/constants.dart new file mode 100755 index 0000000000..0a02de5076 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/constants.dart @@ -0,0 +1,5 @@ +import 'package:flutter/material.dart'; + +class GridHeaderConstants { + static Color get backgroundColor => Colors.grey; +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header.dart new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header_cell.dart new file mode 100755 index 0000000000..eda546416d --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header_cell.dart @@ -0,0 +1,52 @@ +import 'package:app_flowy/workspace/presentation/plugins/grid/grid_sizes.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; +import 'package:flutter/material.dart'; +import 'constants.dart'; + +class HeaderCell extends StatelessWidget { + final Field field; + const HeaderCell(this.field, {Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Text( + field.name, + style: const TextStyle(fontSize: 15.0, color: Colors.black), + ); + } +} + +class HeaderCellContainer extends StatelessWidget { + final HeaderCell child; + final double width; + const HeaderCellContainer({Key? key, required this.child, required this.width}) : super(key: key); + + @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, + ), + ); + } +} + +class HeaderCellLeading extends StatelessWidget { + const HeaderCellLeading({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + width: GridSize.firstHeaderPadding, + color: GridHeaderConstants.backgroundColor, + ); + } +} 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 8c65b29b9b..b58175af0a 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart @@ -9,6 +9,7 @@ import 'package:flowy_sdk/protobuf/flowy-net/event.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-net/network_state.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user/event_map.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder/event_map.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/event_map.pb.dart'; import 'package:isolates/isolates.dart'; import 'package:isolates/ports.dart'; import 'package:ffi/ffi.dart'; @@ -21,6 +22,7 @@ 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-collaboration/protobuf.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart'; // ignore: unused_import import 'package:protobuf/protobuf.dart'; @@ -30,6 +32,7 @@ import 'error.dart'; part 'dart_event/flowy-folder/dart_event.dart'; part 'dart_event/flowy-net/dart_event.dart'; part 'dart_event/flowy-user/dart_event.dart'; +part 'dart_event/flowy-grid/dart_event.dart'; enum FFIException { RequestIsEmpty, 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 3fce9f98db..64e47d37d1 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 @@ -725,7 +725,6 @@ class Cell extends $pb.GeneratedMessage { ..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) ..hasRequiredFields = false ; @@ -734,7 +733,6 @@ class Cell extends $pb.GeneratedMessage { $core.String? id, $core.String? rowId, $core.String? fieldId, - AnyData? data, }) { final _result = create(); if (id != null) { @@ -746,9 +744,6 @@ class Cell extends $pb.GeneratedMessage { if (fieldId != null) { _result.fieldId = fieldId; } - if (data != null) { - _result.data = data; - } return _result; } factory Cell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -798,17 +793,130 @@ class Cell extends $pb.GeneratedMessage { $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); +class DisplayCell extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'DisplayCell', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'content') + ..hasRequiredFields = false + ; + + DisplayCell._() : super(); + factory DisplayCell({ + $core.String? id, + $core.String? content, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (content != null) { + _result.content = content; + } + return _result; + } + factory DisplayCell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory DisplayCell.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') + DisplayCell clone() => DisplayCell()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + DisplayCell copyWith(void Function(DisplayCell) updates) => super.copyWith((message) => updates(message as DisplayCell)) as DisplayCell; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static DisplayCell create() => DisplayCell._(); + DisplayCell createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static DisplayCell getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static DisplayCell? _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 content => $_getSZ(1); + @$pb.TagNumber(2) + set content($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasContent() => $_has(1); + @$pb.TagNumber(2) + void clearContent() => clearField(2); +} + +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') + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: AnyData.create) + ..hasRequiredFields = false + ; + + RawCell._() : super(); + factory RawCell({ + $core.String? id, + AnyData? data, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (data != null) { + _result.data = data; + } + 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) + AnyData get data => $_getN(1); + @$pb.TagNumber(2) + set data(AnyData v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasData() => $_has(1); + @$pb.TagNumber(2) + void clearData() => clearField(2); + @$pb.TagNumber(2) + AnyData ensureData() => $_ensure(1); } 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 dfe0be5c29..93e221828a 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 @@ -159,12 +159,33 @@ const Cell$json = 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'}, ], }; /// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhwKBGRhdGEYBCABKAsyCC5BbnlEYXRhUgRkYXRh'); +final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElk'); +@$core.Deprecated('Use displayCellDescriptor instead') +const DisplayCell$json = const { + '1': 'DisplayCell', + '2': const [ + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'content', '3': 2, '4': 1, '5': 9, '10': 'content'}, + ], +}; + +/// Descriptor for `DisplayCell`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List displayCellDescriptor = $convert.base64Decode('CgtEaXNwbGF5Q2VsbBIOCgJpZBgBIAEoCVICaWQSGAoHY29udGVudBgCIAEoCVIHY29udGVudA=='); +@$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': 'data', '3': 2, '4': 1, '5': 11, '6': '.AnyData', '10': 'data'}, + ], +}; + +/// Descriptor for `RawCell`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List rawCellDescriptor = $convert.base64Decode('CgdSYXdDZWxsEg4KAmlkGAEgASgJUgJpZBIcCgRkYXRhGAIgASgLMgguQW55RGF0YVIEZGF0YQ=='); @$core.Deprecated('Use createGridPayloadDescriptor instead') const CreateGridPayload$json = const { '1': 'CreateGridPayload', 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 092fcbd3db..a0c5d919d3 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -142,8 +142,23 @@ pub struct Cell { #[pb(index = 3)] pub field_id: String, +} - #[pb(index = 4)] +#[derive(Debug, Default, ProtoBuf)] +pub struct DisplayCell { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub content: String, +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct RawCell { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] pub data: AnyData, } 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 127bdfbeb8..52bbd4f113 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 @@ -2405,7 +2405,6 @@ pub struct Cell { pub id: ::std::string::String, pub row_id: ::std::string::String, pub field_id: ::std::string::String, - pub data: ::protobuf::SingularPtrField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -2499,48 +2498,10 @@ impl Cell { 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()) - } } impl ::protobuf::Message for Cell { fn is_initialized(&self) -> bool { - for v in &self.data { - if !v.is_initialized() { - return false; - } - }; true } @@ -2557,9 +2518,6 @@ impl ::protobuf::Message for Cell { 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)?; - }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -2581,10 +2539,6 @@ impl ::protobuf::Message for Cell { 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; - } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -2600,11 +2554,6 @@ impl ::protobuf::Message for Cell { 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)?; - } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -2658,11 +2607,6 @@ impl ::protobuf::Message for Cell { |m: &Cell| { &m.field_id }, |m: &mut Cell| { &mut m.field_id }, )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "data", - |m: &Cell| { &m.data }, - |m: &mut Cell| { &mut m.data }, - )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "Cell", fields, @@ -2682,7 +2626,6 @@ impl ::protobuf::Clear for Cell { self.id.clear(); self.row_id.clear(); self.field_id.clear(); - self.data.clear(); self.unknown_fields.clear(); } } @@ -2699,6 +2642,423 @@ impl ::protobuf::reflect::ProtobufValue for Cell { } } +#[derive(PartialEq,Clone,Default)] +pub struct DisplayCell { + // message fields + pub id: ::std::string::String, + pub content: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a DisplayCell { + fn default() -> &'a DisplayCell { + ::default_instance() + } +} + +impl DisplayCell { + pub fn new() -> DisplayCell { + ::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 content = 2; + + + pub fn get_content(&self) -> &str { + &self.content + } + pub fn clear_content(&mut self) { + self.content.clear(); + } + + // Param is passed by value, moved + pub fn set_content(&mut self, v: ::std::string::String) { + self.content = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_content(&mut self) -> &mut ::std::string::String { + &mut self.content + } + + // Take field + pub fn take_content(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.content, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for DisplayCell { + 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.content)?; + }, + _ => { + ::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.content.is_empty() { + 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); + 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.content.is_empty() { + os.write_string(2, &self.content)?; + } + 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() -> DisplayCell { + DisplayCell::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: &DisplayCell| { &m.id }, + |m: &mut DisplayCell| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "content", + |m: &DisplayCell| { &m.content }, + |m: &mut DisplayCell| { &mut m.content }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "DisplayCell", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static DisplayCell { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(DisplayCell::new) + } +} + +impl ::protobuf::Clear for DisplayCell { + fn clear(&mut self) { + self.id.clear(); + self.content.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for DisplayCell { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for DisplayCell { + 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 data: ::protobuf::SingularPtrField, + // 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()) + } + + // .AnyData data = 2; + + + 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()) + } +} + +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_message_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 let Some(ref v) = self.data.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 let Some(ref v) = self.data.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> 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_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "data", + |m: &RawCell| { &m.data }, + |m: &mut RawCell| { &mut m.data }, + )); + ::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.data.clear(); + 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 CreateGridPayload { // message fields @@ -3107,15 +3467,17 @@ static file_descriptor_proto_data: &'static [u8] = b"\ difiedTime\x12@\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2\x17.Row.Cell\ ByFieldIdEntryR\rcellByFieldId\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\"f\n\x04Cell\x12\x0e\n\x02id\x18\x01\ + \x0b2\x05.CellR\x05value:\x028\x01\"H\n\x04Cell\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\"'\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*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\ + \x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\"7\n\x0bDisplayCell\ + \x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x18\n\x07content\x18\x02\ + \x20\x01(\tR\x07content\"7\n\x07RawCell\x12\x0e\n\x02id\x18\x01\x20\x01(\ + \tR\x02id\x12\x1c\n\x04data\x18\x02\x20\x01(\x0b2\x08.AnyDataR\x04data\"\ + '\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*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/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 012f53aaab..d1233a3e28 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 @@ -52,7 +52,14 @@ message Cell { string id = 1; string row_id = 2; string field_id = 3; - AnyData data = 4; +} +message DisplayCell { + string id = 1; + string content = 2; +} +message RawCell { + string id = 1; + AnyData data = 2; } message CreateGridPayload { string name = 1; From 477fa5f4f646e7d075ecc04460826ec112fe088e Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 3 Mar 2022 22:17:07 +0800 Subject: [PATCH 06/17] feat: config grid bloc --- .../workspace/application/grid/grid_bloc.dart | 82 +- .../application/grid/grid_service.dart | 10 +- .../plugins/grid/grid_layout.dart | 10 +- .../presentation/plugins/grid/grid_page.dart | 10 +- .../widgets/grid_content/cell_builder.dart | 6 +- .../widgets/grid_content/cell_container.dart | 3 +- .../grid/widgets/grid_content/grid_cell.dart | 48 +- .../grid/widgets/grid_content/grid_row.dart | 20 +- .../grid/widgets/grid_header/header.dart | 60 + .../grid/widgets/grid_header/header_cell.dart | 2 +- .../dart_event/flowy-grid/dart_event.dart | 51 + .../flowy-grid-data-model/grid.pb.dart | 340 ++-- .../flowy-grid-data-model/grid.pbjson.dart | 85 +- .../lib/protobuf/flowy-grid/cell_data.pb.dart | 458 +++++ .../protobuf/flowy-grid/cell_data.pbenum.dart | 62 + .../protobuf/flowy-grid/cell_data.pbjson.dart | 125 ++ .../flowy-grid/cell_data.pbserver.dart | 9 + .../protobuf/flowy-grid/event_map.pbenum.dart | 6 + .../protobuf/flowy-grid/event_map.pbjson.dart | 5 +- .../lib/protobuf/flowy-grid/protobuf.dart | 1 + frontend/rust-lib/Cargo.lock | 47 +- frontend/rust-lib/flowy-grid/Cargo.toml | 6 + frontend/rust-lib/flowy-grid/Flowy.toml | 2 +- .../flowy-grid/src/cell_service/cell_data.rs | 469 +++++ .../flowy-grid/src/cell_service/mod.rs | 5 + .../flowy-grid/src/cell_service/stringify.rs | 30 + .../flowy-grid/src/cell_service/util.rs | 129 ++ .../rust-lib/flowy-grid/src/event_handler.rs | 38 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 15 +- frontend/rust-lib/flowy-grid/src/lib.rs | 4 + frontend/rust-lib/flowy-grid/src/macros.rs | 64 + .../src/protobuf/model/cell_data.rs | 1655 +++++++++++++++++ .../src/protobuf/model/event_map.rs | 14 +- .../flowy-grid/src/protobuf/model/mod.rs | 3 + .../src/protobuf/proto/cell_data.proto | 47 + .../src/protobuf/proto/event_map.proto | 3 + shared-lib/Cargo.lock | 2 + shared-lib/flowy-grid-data-model/Cargo.toml | 2 + .../src/entities/grid.rs | 90 +- .../src/protobuf/model/grid.rs | 1069 +++++------ .../src/protobuf/proto/grid.proto | 27 +- 41 files changed, 4209 insertions(+), 905 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbserver.dart create mode 100644 frontend/rust-lib/flowy-grid/src/cell_service/cell_data.rs create mode 100644 frontend/rust-lib/flowy-grid/src/cell_service/mod.rs create mode 100644 frontend/rust-lib/flowy-grid/src/cell_service/stringify.rs create mode 100644 frontend/rust-lib/flowy-grid/src/cell_service/util.rs create mode 100644 frontend/rust-lib/flowy-grid/src/macros.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/cell_data.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_data.proto 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 e6663c4515..d8da9e9d65 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -14,14 +14,17 @@ part 'grid_bloc.freezed.dart'; class GridBloc extends Bloc { final GridService service; final View view; - late Grid _grid; + late Grid? _grid; + late List? _fields; GridBloc({required this.view, required this.service}) : super(GridState.initial()) { on( (event, emit) async { await event.map( initial: (Initial value) async { - await _initial(value, emit); + await _loadGrid(emit); + await _loadFields(emit); + await _loadGridInfo(emit); }, createRow: (_CreateRow value) { service.createRow(gridId: view.id); @@ -39,12 +42,11 @@ class GridBloc extends Bloc { return super.close(); } - Future _initial(Initial value, Emitter emit) async { + Future _loadGrid(Emitter emit) async { final result = await service.openGrid(gridId: view.id); result.fold( (grid) { _grid = grid; - _loadGridInfo(emit); }, (err) { emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))); @@ -52,10 +54,36 @@ class GridBloc extends Bloc { ); } + Future _loadFields(Emitter emit) async { + if (_grid != null) { + final result = await service.getFields(fieldOrders: _grid!.fieldOrders); + result.fold( + (fields) { + _fields = fields.items; + }, + (err) { + emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))); + }, + ); + } + } + Future _loadGridInfo(Emitter emit) async { - emit( - state.copyWith(loadingState: GridLoadingState.finish(left(unit))), - ); + if (_grid != null && _fields != null) { + final result = await service.getRows(rowOrders: _grid!.rowOrders); + result.fold((repeatedRow) { + final rows = repeatedRow.items; + final gridInfo = GridInfo(rows: rows, 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()), + ); + }); + } } } @@ -87,49 +115,33 @@ class GridLoadingState with _$GridLoadingState { const factory GridLoadingState.finish(Either successOrFail) = _Finish; } -typedef FieldById = Map; -typedef RowById = Map; -typedef CellById = Map; - class GridInfo { - List rowOrders; - List fieldOrders; - RowById rowMap; - FieldById fieldMap; + List rows; + List fields; GridInfo({ - required this.rowOrders, - required this.fieldOrders, - required this.fieldMap, - required this.rowMap, + required this.rows, + required this.fields, }); RowInfo rowInfoAtIndex(int index) { - final rowOrder = rowOrders[index]; - final Row row = rowMap[rowOrder.rowId]!; - final cellMap = row.cellByFieldId; - - final displayCellMap = {}; - + final row = rows[index]; return RowInfo( - fieldOrders: fieldOrders, - fieldMap: fieldMap, - displayCellMap: displayCellMap, + fields: fields, + cellMap: row.cellByFieldId, ); } int numberOfRows() { - return rowOrders.length; + return rows.length; } } class RowInfo { - List fieldOrders; - FieldById fieldMap; - CellById displayCellMap; + List fields; + Map cellMap; RowInfo({ - required this.fieldOrders, - required this.fieldMap, - required this.displayCellMap, + required this.fields, + required this.cellMap, }); } 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 b69e4a8e5a..e725f7ac84 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -15,6 +15,14 @@ class GridService { } Future> createRow({required String gridId}) { - throw UnimplementedError(); + return GridEventCreateRow(GridId(value: gridId)).send(); + } + + Future> getRows({required RepeatedRowOrder rowOrders}) { + return GridEventGetRows(rowOrders).send(); + } + + Future> getFields({required RepeatedFieldOrder fieldOrders}) { + return GridEventGetFields(fieldOrders).send(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_layout.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_layout.dart index df2b73cb12..0daeacbb33 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_layout.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_layout.dart @@ -3,14 +3,10 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'grid_sizes.dart'; class GridLayout { - static double headerWidth(List fieldOrders) { - if (fieldOrders.isEmpty) return 0; + static double headerWidth(List fields) { + if (fields.isEmpty) return 0; - final fieldsWidth = fieldOrders - .map( - (fieldOrder) => fieldOrder.width.toDouble(), - ) - .reduce((value, element) => value + element); + final fieldsWidth = fields.map((field) => field.width.toDouble()).reduce((value, element) => value + element); return fieldsWidth + GridSize.firstHeaderPadding; } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_page.dart index 1eb102f7bb..6b72af2aa5 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_page.dart @@ -101,12 +101,12 @@ class _GridBodyState extends State { controller: _scrollController.horizontalController, axis: Axis.horizontal, child: SizedBox( - width: GridLayout.headerWidth(gridInfo.fieldOrders), + width: GridLayout.headerWidth(gridInfo.fields), child: CustomScrollView( physics: StyledScrollPhysics(), controller: _scrollController.verticalController, slivers: [ - _buildHeader(gridInfo.fieldOrders, gridInfo.fieldMap), + _buildHeader(gridInfo.fields), _buildRows(gridInfo), _builderFooter(context), ], @@ -123,9 +123,9 @@ class _GridBodyState extends State { ); } - Widget _buildHeader(List fieldOrders, FieldById fieldById) { + Widget _buildHeader(List fields) { return SliverPersistentHeader( - delegate: GridHeaderDelegate(fieldOrders, fieldById), + delegate: GridHeaderDelegate(fields), floating: true, pinned: true, ); @@ -135,7 +135,7 @@ class _GridBodyState extends State { return SliverList( delegate: SliverChildBuilderDelegate((context, index) { final rowInfo = gridInfo.rowInfoAtIndex(index); - return RepaintBoundary(child: GridRow(rowInfo)); + return RepaintBoundary(child: GridRowWidget(rowInfo)); }, childCount: gridInfo.numberOfRows()), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_builder.dart index a4cab931c9..5ff1922835 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_builder.dart @@ -2,16 +2,16 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'grid_cell.dart'; class GridCellBuilder { - static GridCell buildCell(Field? field, DisplayCell? cell) { + static GridCellWidget buildCell(Field? field, GridCell? cell) { if (field == null || cell == null) { - return BlankCell(); + return const BlankCell(); } switch (field.fieldType) { case FieldType.RichText: return GridTextCell(cell.content); default: - return BlankCell(); + return const BlankCell(); } } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_container.dart index c769a60d34..1ba7c1f009 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_container.dart @@ -1,12 +1,11 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/grid_sizes.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'; import 'grid_cell.dart'; class CellContainer extends StatelessWidget { - final GridCell child; + final GridCellWidget child; final double width; const CellContainer({Key? key, required this.child, required this.width}) : super(key: key); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_cell.dart index a23259c8c3..93701e1ded 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_cell.dart @@ -1,14 +1,18 @@ +import 'package:app_flowy/workspace/presentation/plugins/grid/grid_sizes.dart'; +import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart'; import 'package:flutter/material.dart'; + +import 'cell_decoration.dart'; // ignore: import_of_legacy_library_into_null_safe /// The interface of base cell. -abstract class GridCell extends StatelessWidget { +abstract class GridCellWidget extends StatelessWidget { final canSelect = true; - const GridCell({Key? key}) : super(key: key); + const GridCellWidget({Key? key}) : super(key: key); } -class GridTextCell extends GridCell { +class GridTextCell extends GridCellWidget { final String content; const GridTextCell(this.content, {Key? key}) : super(key: key); @@ -18,7 +22,7 @@ class GridTextCell extends GridCell { } } -class DateCell extends GridCell { +class DateCell extends GridCellWidget { final String content; const DateCell(this.content, {Key? key}) : super(key: key); @@ -28,7 +32,7 @@ class DateCell extends GridCell { } } -class NumberCell extends GridCell { +class NumberCell extends GridCellWidget { final String content; const NumberCell(this.content, {Key? key}) : super(key: key); @@ -38,7 +42,7 @@ class NumberCell extends GridCell { } } -class SingleSelectCell extends GridCell { +class SingleSelectCell extends GridCellWidget { final String content; const SingleSelectCell(this.content, {Key? key}) : super(key: key); @@ -48,7 +52,7 @@ class SingleSelectCell extends GridCell { } } -class MultiSelectCell extends GridCell { +class MultiSelectCell extends GridCellWidget { final String content; const MultiSelectCell(this.content, {Key? key}) : super(key: key); @@ -58,7 +62,7 @@ class MultiSelectCell extends GridCell { } } -class BlankCell extends GridCell { +class BlankCell extends GridCellWidget { const BlankCell({Key? key}) : super(key: key); @override @@ -66,3 +70,31 @@ class BlankCell extends GridCell { return Container(); } } + +class RowLeading extends StatelessWidget { + const RowLeading({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + // return Expanded( + // child: Container( + // color: Colors.white10, + // width: GridSize.firstHeaderPadding, + // ), + // ); + + 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), + ), + ), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_row.dart index 8a1202197e..247f9fc525 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_row.dart @@ -1,22 +1,22 @@ import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/grid_sizes.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'cell_builder.dart'; import 'cell_container.dart'; -import 'grid_row_leading.dart'; +import 'grid_cell.dart'; class GridRowContext { final RepeatedFieldOrder fieldOrders; final Map fieldById; - final Map cellByFieldId; + final Map cellByFieldId; GridRowContext(this.fieldOrders, this.fieldById, this.cellByFieldId); } -class GridRow extends StatelessWidget { +class GridRowWidget extends StatelessWidget { final RowInfo rowInfo; final Function(bool)? onHoverChange; - const GridRow(this.rowInfo, {Key? key, this.onHoverChange}) : super(key: key); + const GridRowWidget(this.rowInfo, {Key? key, this.onHoverChange}) : super(key: key); @override Widget build(BuildContext context) { @@ -48,17 +48,15 @@ class GridRow extends StatelessWidget { var cells = List.empty(growable: true); cells.add(const RowLeading()); - rowInfo.fieldOrders.where((element) => element.visibility).forEach((fieldOrder) { - final field = rowInfo.fieldMap[fieldOrder.fieldId]; - final data = rowInfo.displayCellMap[fieldOrder.fieldId]; - + for (var field in rowInfo.fields) { + final data = rowInfo.cellMap[field.id]; final cell = CellContainer( - width: fieldOrder.width.toDouble(), + width: field.width.toDouble(), child: GridCellBuilder.buildCell(field, data), ); cells.add(cell); - }); + } return cells; } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header.dart index e69de29bb2..51bceb239a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header.dart @@ -0,0 +1,60 @@ +import 'package:app_flowy/workspace/presentation/plugins/grid/grid_sizes.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flutter/material.dart'; + +import 'header_cell.dart'; + +class GridHeaderDelegate extends SliverPersistentHeaderDelegate { + final List fields; + + GridHeaderDelegate(this.fields); + + @override + Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { + return GridHeader(fields: fields); + } + + @override + double get maxExtent => GridSize.headerHeight; + + @override + double get minExtent => GridSize.headerHeight; + + @override + bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) { + if (oldDelegate is GridHeaderDelegate) { + return fields != oldDelegate.fields; + } + return false; + } +} + +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, + ), + ); + + // + headers.add(header); + }); + + return Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const HeaderCellLeading(), + ...headers, + ], + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header_cell.dart index eda546416d..8fbe34fa2b 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header_cell.dart @@ -1,5 +1,5 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/grid_sizes.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flutter/material.dart'; import 'constants.dart'; 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 1c6420c126..21e2804539 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 @@ -35,3 +35,54 @@ class GridEventOpenGrid { } } +class GridEventGetRows { + RepeatedRowOrder request; + GridEventGetRows(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.GetRows.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (okBytes) => left(RepeatedRow.fromBuffer(okBytes)), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + +class GridEventGetFields { + RepeatedFieldOrder request; + GridEventGetFields(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.GetFields.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (okBytes) => left(RepeatedField.fromBuffer(okBytes)), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + +class GridEventCreateRow { + GridId request; + GridEventCreateRow(this.request); + + 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), + (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 64e47d37d1..2d8aeace2c 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 @@ -229,7 +229,6 @@ 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') - ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) ..hasRequiredFields = false ; @@ -237,7 +236,6 @@ class FieldOrder extends $pb.GeneratedMessage { factory FieldOrder({ $core.String? fieldId, $core.bool? visibility, - $core.int? width, }) { final _result = create(); if (fieldId != null) { @@ -246,9 +244,6 @@ class FieldOrder extends $pb.GeneratedMessage { if (visibility != null) { _result.visibility = visibility; } - if (width != null) { - _result.width = width; - } return _result; } factory FieldOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -289,15 +284,6 @@ class FieldOrder extends $pb.GeneratedMessage { $core.bool hasVisibility() => $_has(1); @$pb.TagNumber(2) void clearVisibility() => clearField(2); - - @$pb.TagNumber(3) - $core.int get width => $_getIZ(2); - @$pb.TagNumber(3) - set width($core.int v) { $_setSignedInt32(2, v); } - @$pb.TagNumber(3) - $core.bool hasWidth() => $_has(2); - @$pb.TagNumber(3) - void clearWidth() => clearField(3); } class RepeatedFieldOrder extends $pb.GeneratedMessage { @@ -348,7 +334,8 @@ class Field extends $pb.GeneratedMessage { ..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') - ..aOM(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', subBuilder: AnyData.create) + ..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 ; @@ -359,6 +346,7 @@ class Field extends $pb.GeneratedMessage { $core.String? desc, FieldType? fieldType, $core.bool? frozen, + $core.int? width, AnyData? typeOptions, }) { final _result = create(); @@ -377,6 +365,9 @@ class Field extends $pb.GeneratedMessage { if (frozen != null) { _result.frozen = frozen; } + if (width != null) { + _result.width = width; + } if (typeOptions != null) { _result.typeOptions = typeOptions; } @@ -449,32 +440,82 @@ class Field extends $pb.GeneratedMessage { void clearFrozen() => clearField(5); @$pb.TagNumber(6) - AnyData get typeOptions => $_getN(5); + $core.int get width => $_getIZ(5); @$pb.TagNumber(6) - set typeOptions(AnyData v) { setField(6, v); } + set width($core.int v) { $_setSignedInt32(5, v); } @$pb.TagNumber(6) - $core.bool hasTypeOptions() => $_has(5); + $core.bool hasWidth() => $_has(5); @$pb.TagNumber(6) - void clearTypeOptions() => clearField(6); - @$pb.TagNumber(6) - AnyData ensureTypeOptions() => $_ensure(5); + 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') ? '' : 'typeUrl') + ..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? typeUrl, + $core.String? typeId, $core.List<$core.int>? value, }) { final _result = create(); - if (typeUrl != null) { - _result.typeUrl = typeUrl; + if (typeId != null) { + _result.typeId = typeId; } if (value != null) { _result.value = value; @@ -503,13 +544,13 @@ class AnyData extends $pb.GeneratedMessage { static AnyData? _defaultInstance; @$pb.TagNumber(1) - $core.String get typeUrl => $_getSZ(0); + $core.String get typeId => $_getSZ(0); @$pb.TagNumber(1) - set typeUrl($core.String v) { $_setString(0, v); } + set typeId($core.String v) { $_setString(0, v); } @$pb.TagNumber(1) - $core.bool hasTypeUrl() => $_has(0); + $core.bool hasTypeId() => $_has(0); @$pb.TagNumber(1) - void clearTypeUrl() => clearField(1); + void clearTypeId() => clearField(1); @$pb.TagNumber(2) $core.List<$core.int> get value => $_getN(1); @@ -637,21 +678,21 @@ class RepeatedRowOrder extends $pb.GeneratedMessage { $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) +class GridRow extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridRow', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..aInt64(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'modifiedTime') - ..m<$core.String, Cell>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'Row.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: Cell.create) + ..m<$core.String, GridCell>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'GridRow.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: GridCell.create) ..hasRequiredFields = false ; - Row._() : super(); - factory Row({ + GridRow._() : super(); + factory GridRow({ $core.String? id, $core.String? gridId, $fixnum.Int64? modifiedTime, - $core.Map<$core.String, Cell>? cellByFieldId, + $core.Map<$core.String, GridCell>? cellByFieldId, }) { final _result = create(); if (id != null) { @@ -668,26 +709,26 @@ class Row extends $pb.GeneratedMessage { } return _result; } - factory Row.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Row.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory GridRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridRow.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') - Row clone() => Row()..mergeFromMessage(this); + GridRow clone() => GridRow()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - Row copyWith(void Function(Row) updates) => super.copyWith((message) => updates(message as Row)) as Row; // ignore: deprecated_member_use + GridRow copyWith(void Function(GridRow) updates) => super.copyWith((message) => updates(message as GridRow)) as GridRow; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static Row create() => Row._(); - Row createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static GridRow create() => GridRow._(); + GridRow createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static Row getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static Row? _defaultInstance; + static GridRow getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridRow? _defaultInstance; @$pb.TagNumber(1) $core.String get id => $_getSZ(0); @@ -717,22 +758,65 @@ class Row extends $pb.GeneratedMessage { void clearModifiedTime() => clearField(3); @$pb.TagNumber(4) - $core.Map<$core.String, Cell> get cellByFieldId => $_getMap(3); + $core.Map<$core.String, GridCell> get cellByFieldId => $_getMap(3); } -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') ? '' : 'rowId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') +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: GridRow.create) ..hasRequiredFields = false ; - Cell._() : super(); - factory Cell({ + 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 GridCell extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridCell', 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') ? '' : 'content') + ..hasRequiredFields = false + ; + + GridCell._() : super(); + factory GridCell({ $core.String? id, $core.String? rowId, $core.String? fieldId, + $core.String? content, }) { final _result = create(); if (id != null) { @@ -744,28 +828,31 @@ class Cell extends $pb.GeneratedMessage { if (fieldId != null) { _result.fieldId = fieldId; } + if (content != null) { + _result.content = content; + } return _result; } - factory Cell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Cell.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + factory GridCell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GridCell.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') - Cell clone() => Cell()..mergeFromMessage(this); + GridCell clone() => GridCell()..mergeFromMessage(this); @$core.Deprecated( 'Using this can add significant overhead to your binary. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Will be removed in next major version') - Cell copyWith(void Function(Cell) updates) => super.copyWith((message) => updates(message as Cell)) as Cell; // ignore: deprecated_member_use + GridCell copyWith(void Function(GridCell) updates) => super.copyWith((message) => updates(message as GridCell)) as GridCell; // ignore: deprecated_member_use $pb.BuilderInfo get info_ => _i; @$core.pragma('dart2js:noInline') - static Cell create() => Cell._(); - Cell createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static GridCell create() => GridCell._(); + GridCell createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static Cell getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static Cell? _defaultInstance; + static GridCell getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GridCell? _defaultInstance; @$pb.TagNumber(1) $core.String get id => $_getSZ(0); @@ -793,130 +880,15 @@ class Cell extends $pb.GeneratedMessage { $core.bool hasFieldId() => $_has(2); @$pb.TagNumber(3) void clearFieldId() => clearField(3); -} -class DisplayCell extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'DisplayCell', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'content') - ..hasRequiredFields = false - ; - - DisplayCell._() : super(); - factory DisplayCell({ - $core.String? id, - $core.String? content, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (content != null) { - _result.content = content; - } - return _result; - } - factory DisplayCell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory DisplayCell.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') - DisplayCell clone() => DisplayCell()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - DisplayCell copyWith(void Function(DisplayCell) updates) => super.copyWith((message) => updates(message as DisplayCell)) as DisplayCell; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static DisplayCell create() => DisplayCell._(); - DisplayCell createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static DisplayCell getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static DisplayCell? _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 content => $_getSZ(1); - @$pb.TagNumber(2) - set content($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasContent() => $_has(1); - @$pb.TagNumber(2) - void clearContent() => clearField(2); -} - -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') - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: AnyData.create) - ..hasRequiredFields = false - ; - - RawCell._() : super(); - factory RawCell({ - $core.String? id, - AnyData? data, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (data != null) { - _result.data = data; - } - 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) - AnyData get data => $_getN(1); - @$pb.TagNumber(2) - set data(AnyData v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasData() => $_has(1); - @$pb.TagNumber(2) - void clearData() => clearField(2); - @$pb.TagNumber(2) - AnyData ensureData() => $_ensure(1); + @$pb.TagNumber(4) + $core.String get content => $_getSZ(3); + @$pb.TagNumber(4) + set content($core.String v) { $_setString(3, v); } + @$pb.TagNumber(4) + $core.bool hasContent() => $_has(3); + @$pb.TagNumber(4) + void clearContent() => clearField(4); } class 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 93e221828a..bfbd6266da 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 @@ -64,12 +64,11 @@ const FieldOrder$json = const { '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'}, - const {'1': 'width', '3': 3, '4': 1, '5': 5, '10': 'width'}, ], }; /// Descriptor for `FieldOrder`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEh4KCnZpc2liaWxpdHkYAiABKAhSCnZpc2liaWxpdHkSFAoFd2lkdGgYAyABKAVSBXdpZHRo'); +final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEh4KCnZpc2liaWxpdHkYAiABKAhSCnZpc2liaWxpdHk='); @$core.Deprecated('Use repeatedFieldOrderDescriptor instead') const RepeatedFieldOrder$json = const { '1': 'RepeatedFieldOrder', @@ -89,23 +88,34 @@ const Field$json = const { 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': 'type_options', '3': 6, '4': 1, '5': 11, '6': '.AnyData', '10': 'typeOptions'}, + 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('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIrCgx0eXBlX29wdGlvbnMYBiABKAsyCC5BbnlEYXRhUgt0eXBlT3B0aW9ucw=='); +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_url', '3': 1, '4': 1, '5': 9, '10': 'typeUrl'}, + 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('CgdBbnlEYXRhEhkKCHR5cGVfdXJsGAEgASgJUgd0eXBlVXJsEhQKBXZhbHVlGAIgASgMUgV2YWx1ZQ=='); +final $typed_data.Uint8List anyDataDescriptor = $convert.base64Decode('CgdBbnlEYXRhEhcKB3R5cGVfaWQYASABKAlSBnR5cGVJZBIUCgV2YWx1ZRgCIAEoDFIFdmFsdWU='); @$core.Deprecated('Use rowOrderDescriptor instead') const RowOrder$json = const { '1': 'RowOrder', @@ -128,64 +138,53 @@ const RepeatedRowOrder$json = const { /// Descriptor for `RepeatedRowOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List repeatedRowOrderDescriptor = $convert.base64Decode('ChBSZXBlYXRlZFJvd09yZGVyEh8KBWl0ZW1zGAEgAygLMgkuUm93T3JkZXJSBWl0ZW1z'); -@$core.Deprecated('Use rowDescriptor instead') -const Row$json = const { - '1': 'Row', +@$core.Deprecated('Use gridRowDescriptor instead') +const GridRow$json = const { + '1': 'GridRow', '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': 'modified_time', '3': 3, '4': 1, '5': 3, '10': 'modifiedTime'}, - const {'1': 'cell_by_field_id', '3': 4, '4': 3, '5': 11, '6': '.Row.CellByFieldIdEntry', '10': 'cellByFieldId'}, + const {'1': 'cell_by_field_id', '3': 4, '4': 3, '5': 11, '6': '.GridRow.CellByFieldIdEntry', '10': 'cellByFieldId'}, ], - '3': const [Row_CellByFieldIdEntry$json], + '3': const [GridRow_CellByFieldIdEntry$json], }; -@$core.Deprecated('Use rowDescriptor instead') -const Row_CellByFieldIdEntry$json = const { +@$core.Deprecated('Use gridRowDescriptor instead') +const GridRow_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': '.Cell', '10': 'value'}, + const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.GridCell', '10': 'value'}, ], '7': const {'7': true}, }; -/// Descriptor for `Row`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rowDescriptor = $convert.base64Decode('CgNSb3cSDgoCaWQYASABKAlSAmlkEhcKB2dyaWRfaWQYAiABKAlSBmdyaWRJZBIjCg1tb2RpZmllZF90aW1lGAMgASgDUgxtb2RpZmllZFRpbWUSQAoQY2VsbF9ieV9maWVsZF9pZBgEIAMoCzIXLlJvdy5DZWxsQnlGaWVsZElkRW50cnlSDWNlbGxCeUZpZWxkSWQaRwoSQ2VsbEJ5RmllbGRJZEVudHJ5EhAKA2tleRgBIAEoCVIDa2V5EhsKBXZhbHVlGAIgASgLMgUuQ2VsbFIFdmFsdWU6AjgB'); -@$core.Deprecated('Use cellDescriptor instead') -const Cell$json = const { - '1': 'Cell', +/// Descriptor for `GridRow`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridRowDescriptor = $convert.base64Decode('CgdHcmlkUm93Eg4KAmlkGAEgASgJUgJpZBIXCgdncmlkX2lkGAIgASgJUgZncmlkSWQSIwoNbW9kaWZpZWRfdGltZRgDIAEoA1IMbW9kaWZpZWRUaW1lEkQKEGNlbGxfYnlfZmllbGRfaWQYBCADKAsyGy5HcmlkUm93LkNlbGxCeUZpZWxkSWRFbnRyeVINY2VsbEJ5RmllbGRJZBpLChJDZWxsQnlGaWVsZElkRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSHwoFdmFsdWUYAiABKAsyCS5HcmlkQ2VsbFIFdmFsdWU6AjgB'); +@$core.Deprecated('Use repeatedRowDescriptor instead') +const RepeatedRow$json = const { + '1': 'RepeatedRow', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.GridRow', '10': 'items'}, + ], +}; + +/// Descriptor for `RepeatedRow`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedRowDescriptor = $convert.base64Decode('CgtSZXBlYXRlZFJvdxIeCgVpdGVtcxgBIAMoCzIILkdyaWRSb3dSBWl0ZW1z'); +@$core.Deprecated('Use gridCellDescriptor instead') +const GridCell$json = const { + '1': 'GridCell', '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': 'content', '3': 4, '4': 1, '5': 9, '10': 'content'}, ], }; -/// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElk'); -@$core.Deprecated('Use displayCellDescriptor instead') -const DisplayCell$json = const { - '1': 'DisplayCell', - '2': const [ - const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'content', '3': 2, '4': 1, '5': 9, '10': 'content'}, - ], -}; - -/// Descriptor for `DisplayCell`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List displayCellDescriptor = $convert.base64Decode('CgtEaXNwbGF5Q2VsbBIOCgJpZBgBIAEoCVICaWQSGAoHY29udGVudBgCIAEoCVIHY29udGVudA=='); -@$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': 'data', '3': 2, '4': 1, '5': 11, '6': '.AnyData', '10': 'data'}, - ], -}; - -/// Descriptor for `RawCell`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rawCellDescriptor = $convert.base64Decode('CgdSYXdDZWxsEg4KAmlkGAEgASgJUgJpZBIcCgRkYXRhGAIgASgLMgguQW55RGF0YVIEZGF0YQ=='); +/// Descriptor for `GridCell`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List gridCellDescriptor = $convert.base64Decode('CghHcmlkQ2VsbBIOCgJpZBgBIAEoCVICaWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIZCghmaWVsZF9pZBgDIAEoCVIHZmllbGRJZBIYCgdjb250ZW50GAQgASgJUgdjb250ZW50'); @$core.Deprecated('Use createGridPayloadDescriptor instead') const CreateGridPayload$json = const { '1': 'CreateGridPayload', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pb.dart new file mode 100644 index 0000000000..d87c9e02c7 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pb.dart @@ -0,0 +1,458 @@ +/// +// Generated code. Do not modify. +// source: cell_data.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 'cell_data.pbenum.dart'; + +export 'cell_data.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 SingleSelect extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SingleSelect', 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 + ; + + SingleSelect._() : super(); + factory SingleSelect({ + $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 SingleSelect.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory SingleSelect.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') + SingleSelect clone() => SingleSelect()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SingleSelect copyWith(void Function(SingleSelect) updates) => super.copyWith((message) => updates(message as SingleSelect)) as SingleSelect; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static SingleSelect create() => SingleSelect._(); + SingleSelect createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SingleSelect getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static SingleSelect? _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 MultiSelect extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'MultiSelect', 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 + ; + + MultiSelect._() : super(); + factory MultiSelect({ + $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 MultiSelect.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory MultiSelect.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') + MultiSelect clone() => MultiSelect()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + MultiSelect copyWith(void Function(MultiSelect) updates) => super.copyWith((message) => updates(message as MultiSelect)) as MultiSelect; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static MultiSelect create() => MultiSelect._(); + MultiSelect createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static MultiSelect getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static MultiSelect? _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: FlowyMoney.CNY, valueOf: FlowyMoney.valueOf, enumValues: FlowyMoney.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({ + FlowyMoney? 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) + FlowyMoney get money => $_getN(0); + @$pb.TagNumber(1) + set money(FlowyMoney 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/cell_data.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbenum.dart new file mode 100644 index 0000000000..b6512aafba --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbenum.dart @@ -0,0 +1,62 @@ +/// +// Generated code. Do not modify. +// source: cell_data.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 FlowyMoney extends $pb.ProtobufEnum { + static const FlowyMoney CNY = FlowyMoney._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CNY'); + static const FlowyMoney EUR = FlowyMoney._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EUR'); + static const FlowyMoney USD = FlowyMoney._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'USD'); + + static const $core.List values = [ + CNY, + EUR, + USD, + ]; + + static final $core.Map<$core.int, FlowyMoney> _byValue = $pb.ProtobufEnum.initByValue(values); + static FlowyMoney? valueOf($core.int value) => _byValue[value]; + + const FlowyMoney._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbjson.dart new file mode 100644 index 0000000000..c2caf59394 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbjson.dart @@ -0,0 +1,125 @@ +/// +// Generated code. Do not modify. +// source: cell_data.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 flowyMoneyDescriptor instead') +const FlowyMoney$json = const { + '1': 'FlowyMoney', + '2': const [ + const {'1': 'CNY', '2': 0}, + const {'1': 'EUR', '2': 1}, + const {'1': 'USD', '2': 2}, + ], +}; + +/// Descriptor for `FlowyMoney`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List flowyMoneyDescriptor = $convert.base64Decode('CgpGbG93eU1vbmV5EgcKA0NOWRAAEgcKA0VVUhABEgcKA1VTRBAC'); +@$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 singleSelectDescriptor instead') +const SingleSelect$json = const { + '1': 'SingleSelect', + '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 `SingleSelect`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List singleSelectDescriptor = $convert.base64Decode('CgxTaW5nbGVTZWxlY3QSJwoHb3B0aW9ucxgBIAMoCzINLlNlbGVjdE9wdGlvblIHb3B0aW9ucxIjCg1kaXNhYmxlX2NvbG9yGAIgASgIUgxkaXNhYmxlQ29sb3I='); +@$core.Deprecated('Use multiSelectDescriptor instead') +const MultiSelect$json = const { + '1': 'MultiSelect', + '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 `MultiSelect`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List multiSelectDescriptor = $convert.base64Decode('CgtNdWx0aVNlbGVjdBInCgdvcHRpb25zGAEgAygLMg0uU2VsZWN0T3B0aW9uUgdvcHRpb25zEiMKDWRpc2FibGVfY29sb3IYAiABKAhSDGRpc2FibGVDb2xvcg=='); +@$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': '.FlowyMoney', '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('ChFOdW1iZXJEZXNjcmlwdGlvbhIhCgVtb25leRgBIAEoDjILLkZsb3d5TW9uZXlSBW1vbmV5EhQKBXNjYWxlGAIgASgNUgVzY2FsZRIWCgZzeW1ib2wYAyABKAlSBnN5bWJvbBIjCg1zaWduX3Bvc2l0aXZlGAQgASgIUgxzaWduUG9zaXRpdmUSEgoEbmFtZRgFIAEoCVIEbmFtZQ=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbserver.dart new file mode 100644 index 0000000000..bae86fb5d9 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_data.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: cell_data.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 'cell_data.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 c8b9528369..2b523834c3 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,10 +12,16 @@ import 'package:protobuf/protobuf.dart' as $pb; class GridEvent extends $pb.ProtobufEnum { static const GridEvent CreateGrid = GridEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateGrid'); static const GridEvent OpenGrid = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'OpenGrid'); + static const GridEvent GetRows = GridEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRows'); + static const GridEvent GetFields = GridEvent._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields'); + static const GridEvent CreateRow = GridEvent._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const $core.List values = [ CreateGrid, OpenGrid, + GetRows, + GetFields, + CreateRow, ]; 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 1b16f0b657..19412ddc1d 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,8 +14,11 @@ const GridEvent$json = const { '2': const [ const {'1': 'CreateGrid', '2': 0}, const {'1': 'OpenGrid', '2': 1}, + const {'1': 'GetRows', '2': 2}, + const {'1': 'GetFields', '2': 3}, + const {'1': 'CreateRow', '2': 4}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDgoKQ3JlYXRlR3JpZBAAEgwKCE9wZW5HcmlkEAE='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDgoKQ3JlYXRlR3JpZBAAEgwKCE9wZW5HcmlkEAESCwoHR2V0Um93cxACEg0KCUdldEZpZWxkcxADEg0KCUNyZWF0ZVJvdxAE'); 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 a5735f1a1a..39a722893a 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,2 +1,3 @@ // Auto-generated, do not edit +export './cell_data.pb.dart'; export './event_map.pb.dart'; diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index dec40ba22d..05d59f7879 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -57,6 +57,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + [[package]] name = "async-stream" version = "0.3.2" @@ -1042,15 +1048,21 @@ dependencies = [ name = "flowy-grid" version = "0.1.0" dependencies = [ + "bytes", + "chrono", "flowy-derive", "flowy-error", "flowy-grid-data-model", + "lazy_static", "lib-dispatch", "lib-infra", "protobuf", + "rust_decimal", + "rusty-money", "strum", "strum_macros", "tracing", + "uuid", ] [[package]] @@ -1061,6 +1073,8 @@ dependencies = [ "flowy-derive", "lib-infra", "protobuf", + "strum", + "strum_macros", ] [[package]] @@ -1702,7 +1716,7 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" dependencies = [ - "arrayvec", + "arrayvec 0.5.2", "bitflags", "cfg-if", "ryu", @@ -2752,6 +2766,27 @@ dependencies = [ "winreg", ] +[[package]] +name = "rust_decimal" +version = "1.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d37baa70cf8662d2ba1c1868c5983dda16ef32b105cce41fb5c47e72936a90b3" +dependencies = [ + "arrayvec 0.7.2", + "num-traits", + "serde", +] + +[[package]] +name = "rust_decimal_macros" +version = "1.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "184abaf7b434800e1a5a8aad3ebc8cd7498df33af72d65371d797a264713a59b" +dependencies = [ + "quote", + "rust_decimal", +] + [[package]] name = "rustc-demangle" version = "0.1.21" @@ -2773,6 +2808,16 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" +[[package]] +name = "rusty-money" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b28f881005eac7ad8d46b6f075da5f322bd7f4f83a38720fc069694ddadd683" +dependencies = [ + "rust_decimal", + "rust_decimal_macros", +] + [[package]] name = "ryu" version = "1.0.9" diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index b2d58b7794..31030c5d28 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -15,6 +15,12 @@ strum_macros = "0.21" flowy-derive = { path = "../../../shared-lib/flowy-derive" } tracing = { version = "0.1", features = ["log"] } protobuf = {version = "2.18.0"} +rust_decimal = "1.8.1" +rusty-money = {version = "0.4.0", features = ["iso"]} +lazy_static = "1.4.0" +chrono = "0.4.19" +uuid = { version = "0.8", features = ["serde", "v4"] } +bytes = { version = "1.0" } [build-dependencies] lib-infra = { path = "../../../shared-lib/lib-infra", features = ["protobuf_file_gen", "proto_gen"] } diff --git a/frontend/rust-lib/flowy-grid/Flowy.toml b/frontend/rust-lib/flowy-grid/Flowy.toml index 934d557323..1f99bcf43d 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"] +proto_crates = ["src/event_map.rs", "src/cell_service/cell_data.rs"] event_files = ["src/event_map.rs"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/src/cell_service/cell_data.rs b/frontend/rust-lib/flowy-grid/src/cell_service/cell_data.rs new file mode 100644 index 0000000000..fdd62b796c --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/cell_service/cell_data.rs @@ -0,0 +1,469 @@ +use crate::cell_service::util::*; +use crate::impl_any_data; +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 rust_decimal::Decimal; +use rusty_money::{ + iso::{Currency, CNY, EUR, USD}, + Money, +}; +use std::str::FromStr; + +use strum::IntoEnumIterator; +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 StringifyAnyData for RichTextDescription { + fn stringify_any_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() + } +} + +// Checkbox +#[derive(Debug, ProtoBuf, Default)] +pub struct CheckboxDescription { + #[pb(index = 1)] + pub is_selected: bool, +} +impl_any_data!(CheckboxDescription, FieldType::Checkbox); + +impl StringifyAnyData for CheckboxDescription { + fn stringify_any_data(&self, data: &AnyData) -> String { + data.to_string() + } + + fn str_to_any_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() + } +} + +// Date +#[derive(Clone, Debug, ProtoBuf)] +pub struct DateDescription { + #[pb(index = 1)] + pub date_format: DateFormat, + + #[pb(index = 2)] + pub time_format: TimeFormat, +} +impl_any_data!(DateDescription, FieldType::DateTime); + +impl std::default::Default for DateDescription { + fn default() -> Self { + DateDescription { + date_format: DateFormat::default(), + time_format: TimeFormat::default(), + } + } +} + +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 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 { + match String::from_utf8(data.value.clone()) { + 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() + } + }, + Err(e) => { + tracing::error!("DateDescription stringify any_data failed. {:?}", e); + String::new() + } + } + } + + fn str_to_any_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), + )) + } +} + +#[derive(Clone, Debug, Copy, 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, 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, ProtoBuf, Default)] +pub struct SingleSelect { + #[pb(index = 1)] + pub options: Vec, + + #[pb(index = 2)] + pub disable_color: bool, +} +impl_any_data!(SingleSelect, FieldType::SingleSelect); + +impl StringifyAnyData for SingleSelect { + fn stringify_any_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() + } +} + +// Multiple select +#[derive(Clone, Debug, ProtoBuf, Default)] +pub struct MultiSelect { + #[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 { + 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() + } +} + +#[derive(Clone, Debug, ProtoBuf, Default)] +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, ProtoBuf)] +pub struct NumberDescription { + #[pb(index = 1)] + pub money: FlowyMoney, + + #[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_any_data!(NumberDescription, FieldType::Number); + +impl std::default::Default for NumberDescription { + fn default() -> Self { + NumberDescription { + money: FlowyMoney::default(), + scale: 0, + symbol: String::new(), + sign_positive: true, + name: String::new(), + } + } +} + +impl NumberDescription { + pub fn set_money(&mut self, money: FlowyMoney) { + self.money = money; + self.symbol = money.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()) + } + Err(e) => { + tracing::error!("Parser money from {} failed: {:?}", s, e); + None + } + } + } +} + +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 { + match String::from_utf8(data.value.clone()) { + 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_to_any_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)) + } +} + +#[derive(Clone, Copy, Debug, EnumIter, ProtoBuf_Enum)] +pub enum FlowyMoney { + CNY = 0, + EUR = 1, + USD = 2, +} + +impl std::default::Default for FlowyMoney { + fn default() -> Self { + FlowyMoney::USD + } +} + +impl FlowyMoney { + // Currency list https://docs.rs/rusty-money/0.4.0/rusty_money/iso/index.html + pub fn from_str(s: &str) -> FlowyMoney { + match s { + "CNY" => FlowyMoney::CNY, + "EUR" => FlowyMoney::EUR, + "USD" => FlowyMoney::USD, + _ => FlowyMoney::CNY, + } + } + + pub fn from_money(money: &rusty_money::Money) -> FlowyMoney { + FlowyMoney::from_str(&money.currency().symbol.to_string()) + } + + pub fn currency(&self) -> &'static Currency { + match self { + FlowyMoney::CNY => CNY, + FlowyMoney::EUR => EUR, + FlowyMoney::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(&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/cell_service/mod.rs b/frontend/rust-lib/flowy-grid/src/cell_service/mod.rs new file mode 100644 index 0000000000..b781258695 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/cell_service/mod.rs @@ -0,0 +1,5 @@ +mod stringify; +mod util; + +pub mod cell_data; +pub use stringify::*; diff --git a/frontend/rust-lib/flowy-grid/src/cell_service/stringify.rs b/frontend/rust-lib/flowy-grid/src/cell_service/stringify.rs new file mode 100644 index 0000000000..0163a38368 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/cell_service/stringify.rs @@ -0,0 +1,30 @@ +use crate::cell_service::cell_data::*; +use crate::cell_service::util::*; +use flowy_error::FlowyError; +use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; + +pub trait AnyDataSerde { + fn 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), + } + } + + fn 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/cell_service/util.rs b/frontend/rust-lib/flowy-grid/src/cell_service/util.rs new file mode 100644 index 0000000000..7081b6d4f0 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/cell_service/util.rs @@ -0,0 +1,129 @@ +use crate::cell_service::cell_data::FlowyMoney; +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 FlowyMoney::iter() { + map.insert(money.symbol(), 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 = FlowyMoney::from_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(FlowyMoney::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(); + } + } +} + +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/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 0d7b0a9f90..765da724d5 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,7 +1,9 @@ use crate::controller::GridManager; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{CreateGridPayload, Grid, GridId}; -use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; +use flowy_grid_data_model::entities::{ + CreateGridPayload, Grid, GridId, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, +}; +use lib_dispatch::prelude::{AppData, Data, DataResult}; use std::sync::Arc; #[tracing::instrument(skip(data, controller), err)] @@ -17,7 +19,37 @@ pub(crate) async fn open_grid_handler( data: Data, controller: AppData>, ) -> DataResult { - let params: GridId = data.into_inner(); + let _params: GridId = data.into_inner(); + + todo!() +} + +#[tracing::instrument(skip(data, controller), err)] +pub(crate) async fn get_rows_handler( + data: Data, + controller: AppData>, +) -> DataResult { + let row_orders: RepeatedRowOrder = data.into_inner(); + + todo!() +} + +#[tracing::instrument(skip(data, controller), err)] +pub(crate) async fn get_fields_handler( + data: Data, + controller: AppData>, +) -> DataResult { + let field_orders: RepeatedFieldOrder = data.into_inner(); + + todo!() +} + +#[tracing::instrument(skip(data, controller), err)] +pub(crate) async fn create_row_handler( + data: Data, + controller: AppData>, +) -> DataResult { + let id: GridId = data.into_inner(); todo!() } diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index b1caa3993f..3fce720d36 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -7,10 +7,12 @@ use strum_macros::Display; pub fn create(grid_manager: Arc) -> Module { let mut module = Module::new().name(env!("CARGO_PKG_NAME")).data(grid_manager); - module = module .event(GridEvent::CreateGrid, create_grid_handler) - .event(GridEvent::OpenGrid, open_grid_handler); + .event(GridEvent::OpenGrid, open_grid_handler) + .event(GridEvent::GetRows, get_rows_handler) + .event(GridEvent::GetFields, get_fields_handler) + .event(GridEvent::CreateRow, create_row_handler); module } @@ -23,4 +25,13 @@ pub enum GridEvent { #[event(input = "GridId", output = "Grid")] OpenGrid = 1, + + #[event(input = "RepeatedRowOrder", output = "RepeatedRow")] + GetRows = 2, + + #[event(input = "RepeatedFieldOrder", output = "RepeatedField")] + GetFields = 3, + + #[event(input = "GridId")] + CreateRow = 4, } diff --git a/frontend/rust-lib/flowy-grid/src/lib.rs b/frontend/rust-lib/flowy-grid/src/lib.rs index 65726c3dbd..b7a4baf831 100644 --- a/frontend/rust-lib/flowy-grid/src/lib.rs +++ b/frontend/rust-lib/flowy-grid/src/lib.rs @@ -1,5 +1,9 @@ +#[macro_use] +mod macros; + mod controller; mod event_handler; mod event_map; +mod cell_service; mod protobuf; diff --git a/frontend/rust-lib/flowy-grid/src/macros.rs b/frontend/rust-lib/flowy-grid/src/macros.rs new file mode 100644 index 0000000000..043dcccb44 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/macros.rs @@ -0,0 +1,64 @@ +#[macro_export] +macro_rules! impl_any_data { + ($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); + }; +} + +#[macro_export] +macro_rules! impl_field_type_data_from_field { + ($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())) { + Ok(obj) => obj, + Err(err) => { + tracing::error!("{} convert from any data failed, {:?}", stringify!($target), err); + $target::default() + } + } + } + } + }; +} + +#[macro_export] +macro_rules! impl_type_option_from_field_data { + ($target: ident, $field_type:expr) => { + impl $target { + pub fn field_type() -> FieldType { + $field_type + } + } + + impl std::convert::From<$target> for AnyData { + fn from(field_data: $target) -> Self { + match field_data.try_into() { + Ok(bytes) => { + let bytes: Bytes = bytes; + AnyData::from_bytes(&$target::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) + } + } + } + } + }; +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_data.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_data.rs new file mode 100644 index 0000000000..d173fe22d0 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_data.rs @@ -0,0 +1,1655 @@ +// 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 `cell_data.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 SingleSelect { + // 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 SingleSelect { + fn default() -> &'a SingleSelect { + ::default_instance() + } +} + +impl SingleSelect { + pub fn new() -> SingleSelect { + ::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 SingleSelect { + 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() -> SingleSelect { + SingleSelect::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: &SingleSelect| { &m.options }, + |m: &mut SingleSelect| { &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 }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "SingleSelect", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static SingleSelect { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(SingleSelect::new) + } +} + +impl ::protobuf::Clear for SingleSelect { + fn clear(&mut self) { + self.options.clear(); + self.disable_color = false; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for SingleSelect { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for SingleSelect { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct MultiSelect { + // 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 MultiSelect { + fn default() -> &'a MultiSelect { + ::default_instance() + } +} + +impl MultiSelect { + pub fn new() -> MultiSelect { + ::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 MultiSelect { + 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() -> MultiSelect { + MultiSelect::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: &MultiSelect| { &m.options }, + |m: &mut MultiSelect| { &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 }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MultiSelect", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MultiSelect { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MultiSelect::new) + } +} + +impl ::protobuf::Clear for MultiSelect { + fn clear(&mut self) { + self.options.clear(); + self.disable_color = false; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MultiSelect { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MultiSelect { + 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: FlowyMoney, + 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() + } + + // .FlowyMoney money = 1; + + + pub fn get_money(&self) -> FlowyMoney { + self.money + } + pub fn clear_money(&mut self) { + self.money = FlowyMoney::CNY; + } + + // Param is passed by value, moved + pub fn set_money(&mut self, v: FlowyMoney) { + 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 != FlowyMoney::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 != FlowyMoney::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 = FlowyMoney::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 FlowyMoney { + CNY = 0, + EUR = 1, + USD = 2, +} + +impl ::protobuf::ProtobufEnum for FlowyMoney { + fn value(&self) -> i32 { + *self as i32 + } + + 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), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [FlowyMoney] = &[ + FlowyMoney::CNY, + FlowyMoney::EUR, + FlowyMoney::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::("FlowyMoney", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for FlowyMoney { +} + +impl ::std::default::Default for FlowyMoney { + fn default() -> Self { + FlowyMoney::CNY + } +} + +impl ::protobuf::reflect::ProtobufValue for FlowyMoney { + 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\ + \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\ +"; + +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/event_map.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs index d4c95c928b..b2456ff055 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,6 +27,9 @@ pub enum GridEvent { CreateGrid = 0, OpenGrid = 1, + GetRows = 2, + GetFields = 3, + CreateRow = 4, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -38,6 +41,9 @@ impl ::protobuf::ProtobufEnum for GridEvent { match value { 0 => ::std::option::Option::Some(GridEvent::CreateGrid), 1 => ::std::option::Option::Some(GridEvent::OpenGrid), + 2 => ::std::option::Option::Some(GridEvent::GetRows), + 3 => ::std::option::Option::Some(GridEvent::GetFields), + 4 => ::std::option::Option::Some(GridEvent::CreateRow), _ => ::std::option::Option::None } } @@ -46,6 +52,9 @@ impl ::protobuf::ProtobufEnum for GridEvent { static values: &'static [GridEvent] = &[ GridEvent::CreateGrid, GridEvent::OpenGrid, + GridEvent::GetRows, + GridEvent::GetFields, + GridEvent::CreateRow, ]; values } @@ -74,8 +83,9 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*)\n\tGridEvent\x12\x0e\n\nCreateGrid\x10\0\x12\x0c\ - \n\x08OpenGrid\x10\x01b\x06proto3\ + \n\x0fevent_map.proto*T\n\tGridEvent\x12\x0e\n\nCreateGrid\x10\0\x12\x0c\ + \n\x08OpenGrid\x10\x01\x12\x0b\n\x07GetRows\x10\x02\x12\r\n\tGetFields\ + \x10\x03\x12\r\n\tCreateRow\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/model/mod.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs index 56c0b3d949..55aeddc863 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs @@ -1,5 +1,8 @@ #![cfg_attr(rustfmt, rustfmt::skip)] // Auto-generated, do not edit +mod cell_data; +pub use cell_data::*; + mod event_map; pub use event_map::*; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_data.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_data.proto new file mode 100644 index 0000000000..dc146af19e --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_data.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; + +message RichTextDescription { + string format = 1; +} +message CheckboxDescription { + bool is_selected = 1; +} +message DateDescription { + DateFormat date_format = 1; + TimeFormat time_format = 2; +} +message SingleSelect { + repeated SelectOption options = 1; + bool disable_color = 2; +} +message MultiSelect { + repeated SelectOption options = 1; + bool disable_color = 2; +} +message SelectOption { + string id = 1; + string name = 2; + string color = 3; +} +message NumberDescription { + FlowyMoney 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 FlowyMoney { + CNY = 0; + EUR = 1; + USD = 2; +} 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 f1a860aee0..82819b6bd5 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,4 +3,7 @@ syntax = "proto3"; enum GridEvent { CreateGrid = 0; OpenGrid = 1; + GetRows = 2; + GetFields = 3; + CreateRow = 4; } diff --git a/shared-lib/Cargo.lock b/shared-lib/Cargo.lock index 5b242f5fd6..4afa34ed29 100644 --- a/shared-lib/Cargo.lock +++ b/shared-lib/Cargo.lock @@ -486,6 +486,8 @@ dependencies = [ "flowy-derive", "lib-infra", "protobuf", + "strum", + "strum_macros", ] [[package]] diff --git a/shared-lib/flowy-grid-data-model/Cargo.toml b/shared-lib/flowy-grid-data-model/Cargo.toml index c929ab4b76..8281121c44 100644 --- a/shared-lib/flowy-grid-data-model/Cargo.toml +++ b/shared-lib/flowy-grid-data-model/Cargo.toml @@ -9,6 +9,8 @@ edition = "2021" flowy-derive = { path = "../flowy-derive" } protobuf = {version = "2.18.0"} bytes = "1.0" +strum = "0.21" +strum_macros = "0.21" [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 a0c5d919d3..03e738faee 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,8 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use std::collections::HashMap; +use strum_macros::{Display, EnumIter, EnumString}; + #[derive(Debug, Default, ProtoBuf)] pub struct Grid { #[pb(index = 1)] @@ -41,9 +43,6 @@ pub struct FieldOrder { #[pb(index = 2)] pub visibility: bool, - - #[pb(index = 3)] - pub width: i32, } #[derive(Debug, Default, ProtoBuf)] @@ -53,7 +52,6 @@ pub struct RepeatedFieldOrder { } #[derive(Debug, Default, ProtoBuf)] - pub struct Field { #[pb(index = 1)] pub id: String, @@ -71,10 +69,19 @@ pub struct Field { pub frozen: bool, #[pb(index = 6)] + pub width: i32, + + #[pb(index = 7)] pub type_options: AnyData, } -#[derive(Debug, ProtoBuf_Enum)] +#[derive(Debug, Default, ProtoBuf)] +pub struct RepeatedField { + #[pb(index = 1)] + pub items: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display)] pub enum FieldType { RichText = 0, Number = 1, @@ -90,15 +97,57 @@ impl std::default::Default for FieldType { } } +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, Default, ProtoBuf)] pub struct AnyData { #[pb(index = 1)] - pub type_url: String, + 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, ProtoBuf)] pub struct RowOrder { #[pb(index = 1)] @@ -118,7 +167,7 @@ pub struct RepeatedRowOrder { } #[derive(Debug, Default, ProtoBuf)] -pub struct Row { +pub struct GridRow { #[pb(index = 1)] pub id: String, @@ -129,11 +178,17 @@ pub struct Row { pub modified_time: i64, #[pb(index = 4)] - pub cell_by_field_id: HashMap, + pub cell_by_field_id: HashMap, } #[derive(Debug, Default, ProtoBuf)] -pub struct Cell { +pub struct RepeatedRow { + #[pb(index = 1)] + pub items: Vec, +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct GridCell { #[pb(index = 1)] pub id: String, @@ -142,26 +197,11 @@ pub struct Cell { #[pb(index = 3)] pub field_id: String, -} -#[derive(Debug, Default, ProtoBuf)] -pub struct DisplayCell { - #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] + #[pb(index = 4)] pub content: String, } -#[derive(Debug, Default, ProtoBuf)] -pub struct RawCell { - #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub data: AnyData, -} - #[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 52bbd4f113..820ac7404c 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 @@ -767,7 +767,6 @@ pub struct FieldOrder { // message fields pub field_id: ::std::string::String, pub visibility: bool, - pub width: i32, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -824,21 +823,6 @@ impl FieldOrder { pub fn set_visibility(&mut self, v: bool) { self.visibility = v; } - - // int32 width = 3; - - - 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 FieldOrder { @@ -860,13 +844,6 @@ impl ::protobuf::Message for FieldOrder { let tmp = is.read_bool()?; self.visibility = 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.width = tmp; - }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -885,9 +862,6 @@ impl ::protobuf::Message for FieldOrder { if self.visibility != false { my_size += 2; } - if self.width != 0 { - my_size += ::protobuf::rt::value_size(3, 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 @@ -900,9 +874,6 @@ impl ::protobuf::Message for FieldOrder { if self.visibility != false { os.write_bool(2, self.visibility)?; } - if self.width != 0 { - os.write_int32(3, self.width)?; - } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -951,11 +922,6 @@ impl ::protobuf::Message for FieldOrder { |m: &FieldOrder| { &m.visibility }, |m: &mut FieldOrder| { &mut m.visibility }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( - "width", - |m: &FieldOrder| { &m.width }, - |m: &mut FieldOrder| { &mut m.width }, - )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "FieldOrder", fields, @@ -974,7 +940,6 @@ impl ::protobuf::Clear for FieldOrder { fn clear(&mut self) { self.field_id.clear(); self.visibility = false; - self.width = 0; self.unknown_fields.clear(); } } @@ -1165,6 +1130,7 @@ pub struct Field { 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, @@ -1290,7 +1256,22 @@ impl Field { self.frozen = v; } - // .AnyData type_options = 6; + // 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 { @@ -1358,6 +1339,13 @@ impl ::protobuf::Message for Field { 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)?; }, _ => { @@ -1387,6 +1375,9 @@ impl ::protobuf::Message for Field { 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; @@ -1412,8 +1403,11 @@ impl ::protobuf::Message for Field { 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(6, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_tag(7, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; } @@ -1480,6 +1474,11 @@ impl ::protobuf::Message for Field { |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 }, @@ -1506,6 +1505,7 @@ impl ::protobuf::Clear for Field { self.desc.clear(); self.field_type = FieldType::RichText; self.frozen = false; + self.width = 0; self.type_options.clear(); self.unknown_fields.clear(); } @@ -1523,10 +1523,176 @@ 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 AnyData { // message fields - pub type_url: ::std::string::String, + pub type_id: ::std::string::String, pub value: ::std::vec::Vec, // special fields pub unknown_fields: ::protobuf::UnknownFields, @@ -1544,30 +1710,30 @@ impl AnyData { ::std::default::Default::default() } - // string type_url = 1; + // string type_id = 1; - pub fn get_type_url(&self) -> &str { - &self.type_url + pub fn get_type_id(&self) -> &str { + &self.type_id } - pub fn clear_type_url(&mut self) { - self.type_url.clear(); + pub fn clear_type_id(&mut self) { + self.type_id.clear(); } // Param is passed by value, moved - pub fn set_type_url(&mut self, v: ::std::string::String) { - self.type_url = v; + 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_url(&mut self) -> &mut ::std::string::String { - &mut self.type_url + pub fn mut_type_id(&mut self) -> &mut ::std::string::String { + &mut self.type_id } // Take field - pub fn take_type_url(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.type_url, ::std::string::String::new()) + pub fn take_type_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.type_id, ::std::string::String::new()) } // bytes value = 2; @@ -1607,7 +1773,7 @@ impl ::protobuf::Message for AnyData { 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_url)?; + ::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)?; @@ -1624,8 +1790,8 @@ impl ::protobuf::Message for AnyData { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if !self.type_url.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.type_url); + 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); @@ -1636,8 +1802,8 @@ impl ::protobuf::Message for AnyData { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.type_url.is_empty() { - os.write_string(1, &self.type_url)?; + if !self.type_id.is_empty() { + os.write_string(1, &self.type_id)?; } if !self.value.is_empty() { os.write_bytes(2, &self.value)?; @@ -1681,9 +1847,9 @@ impl ::protobuf::Message for AnyData { descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "type_url", - |m: &AnyData| { &m.type_url }, - |m: &mut AnyData| { &mut m.type_url }, + "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", @@ -1706,7 +1872,7 @@ impl ::protobuf::Message for AnyData { impl ::protobuf::Clear for AnyData { fn clear(&mut self) { - self.type_url.clear(); + self.type_id.clear(); self.value.clear(); self.unknown_fields.clear(); } @@ -2127,25 +2293,25 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedRowOrder { } #[derive(PartialEq,Clone,Default)] -pub struct Row { +pub struct GridRow { // message fields pub id: ::std::string::String, pub grid_id: ::std::string::String, pub modified_time: i64, - pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, Cell>, + pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, GridCell>, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a Row { - fn default() -> &'a Row { - ::default_instance() +impl<'a> ::std::default::Default for &'a GridRow { + fn default() -> &'a GridRow { + ::default_instance() } } -impl Row { - pub fn new() -> Row { +impl GridRow { + pub fn new() -> GridRow { ::std::default::Default::default() } @@ -2216,10 +2382,10 @@ impl Row { self.modified_time = v; } - // repeated .Row.CellByFieldIdEntry cell_by_field_id = 4; + // repeated .GridRow.CellByFieldIdEntry cell_by_field_id = 4; - pub fn get_cell_by_field_id(&self) -> &::std::collections::HashMap<::std::string::String, Cell> { + pub fn get_cell_by_field_id(&self) -> &::std::collections::HashMap<::std::string::String, GridCell> { &self.cell_by_field_id } pub fn clear_cell_by_field_id(&mut self) { @@ -2227,22 +2393,22 @@ impl Row { } // Param is passed by value, moved - pub fn set_cell_by_field_id(&mut self, v: ::std::collections::HashMap<::std::string::String, Cell>) { + pub fn set_cell_by_field_id(&mut self, v: ::std::collections::HashMap<::std::string::String, GridCell>) { 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, Cell> { + pub fn mut_cell_by_field_id(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, GridCell> { &mut self.cell_by_field_id } // Take field - pub fn take_cell_by_field_id(&mut self) -> ::std::collections::HashMap<::std::string::String, Cell> { + pub fn take_cell_by_field_id(&mut self) -> ::std::collections::HashMap<::std::string::String, GridCell> { ::std::mem::replace(&mut self.cell_by_field_id, ::std::collections::HashMap::new()) } } -impl ::protobuf::Message for Row { +impl ::protobuf::Message for GridRow { fn is_initialized(&self) -> bool { true } @@ -2265,7 +2431,7 @@ impl ::protobuf::Message for Row { self.modified_time = tmp; }, 4 => { - ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; + ::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())?; @@ -2288,7 +2454,7 @@ impl ::protobuf::Message for Row { if self.modified_time != 0 { my_size += ::protobuf::rt::value_size(3, self.modified_time, ::protobuf::wire_format::WireTypeVarint); } - my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(4, &self.cell_by_field_id); + my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(4, &self.cell_by_field_id); my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -2304,7 +2470,7 @@ impl ::protobuf::Message for Row { if self.modified_time != 0 { os.write_int64(3, self.modified_time)?; } - ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(4, &self.cell_by_field_id, os)?; + ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(4, &self.cell_by_field_id, os)?; os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -2335,8 +2501,8 @@ impl ::protobuf::Message for Row { Self::descriptor_static() } - fn new() -> Row { - Row::new() + fn new() -> GridRow { + GridRow::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -2345,39 +2511,39 @@ impl ::protobuf::Message for Row { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "id", - |m: &Row| { &m.id }, - |m: &mut Row| { &mut m.id }, + |m: &GridRow| { &m.id }, + |m: &mut GridRow| { &mut m.id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "grid_id", - |m: &Row| { &m.grid_id }, - |m: &mut Row| { &mut m.grid_id }, + |m: &GridRow| { &m.grid_id }, + |m: &mut GridRow| { &mut m.grid_id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( "modified_time", - |m: &Row| { &m.modified_time }, - |m: &mut Row| { &mut m.modified_time }, + |m: &GridRow| { &m.modified_time }, + |m: &mut GridRow| { &mut m.modified_time }, )); - fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( "cell_by_field_id", - |m: &Row| { &m.cell_by_field_id }, - |m: &mut Row| { &mut m.cell_by_field_id }, + |m: &GridRow| { &m.cell_by_field_id }, + |m: &mut GridRow| { &mut m.cell_by_field_id }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "Row", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridRow", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static Row { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(Row::new) + fn default_instance() -> &'static GridRow { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridRow::new) } } -impl ::protobuf::Clear for Row { +impl ::protobuf::Clear for GridRow { fn clear(&mut self) { self.id.clear(); self.grid_id.clear(); @@ -2387,37 +2553,204 @@ impl ::protobuf::Clear for Row { } } -impl ::std::fmt::Debug for Row { +impl ::std::fmt::Debug for GridRow { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for Row { +impl ::protobuf::reflect::ProtobufValue for GridRow { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } } #[derive(PartialEq,Clone,Default)] -pub struct Cell { +pub struct RepeatedRow { // message fields - pub id: ::std::string::String, - pub row_id: ::std::string::String, - pub field_id: ::std::string::String, + pub items: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a Cell { - fn default() -> &'a Cell { - ::default_instance() +impl<'a> ::std::default::Default for &'a RepeatedRow { + fn default() -> &'a RepeatedRow { + ::default_instance() } } -impl Cell { - pub fn new() -> Cell { +impl RepeatedRow { + pub fn new() -> RepeatedRow { + ::std::default::Default::default() + } + + // repeated .GridRow items = 1; + + + pub fn get_items(&self) -> &[GridRow] { + &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 GridCell { + // message fields + pub id: ::std::string::String, + pub row_id: ::std::string::String, + pub field_id: ::std::string::String, + pub content: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a GridCell { + fn default() -> &'a GridCell { + ::default_instance() + } +} + +impl GridCell { + pub fn new() -> GridCell { ::std::default::Default::default() } @@ -2498,198 +2831,8 @@ impl Cell { pub fn take_field_id(&mut self) -> ::std::string::String { ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) } -} -impl ::protobuf::Message for Cell { - 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)?; - }, - _ => { - ::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); - } - 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)?; - } - 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() -> Cell { - Cell::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: &Cell| { &m.id }, - |m: &mut Cell| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_id", - |m: &Cell| { &m.row_id }, - |m: &mut Cell| { &mut m.row_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "field_id", - |m: &Cell| { &m.field_id }, - |m: &mut Cell| { &mut m.field_id }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "Cell", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static Cell { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(Cell::new) - } -} - -impl ::protobuf::Clear for Cell { - fn clear(&mut self) { - self.id.clear(); - self.row_id.clear(); - self.field_id.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Cell { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Cell { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct DisplayCell { - // message fields - pub id: ::std::string::String, - pub content: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a DisplayCell { - fn default() -> &'a DisplayCell { - ::default_instance() - } -} - -impl DisplayCell { - pub fn new() -> DisplayCell { - ::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 content = 2; + // string content = 4; pub fn get_content(&self) -> &str { @@ -2716,7 +2859,7 @@ impl DisplayCell { } } -impl ::protobuf::Message for DisplayCell { +impl ::protobuf::Message for GridCell { fn is_initialized(&self) -> bool { true } @@ -2729,6 +2872,12 @@ impl ::protobuf::Message for DisplayCell { ::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.content)?; }, _ => { @@ -2746,8 +2895,14 @@ impl ::protobuf::Message for DisplayCell { 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.content.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.content); + my_size += ::protobuf::rt::string_size(4, &self.content); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -2758,8 +2913,14 @@ impl ::protobuf::Message for DisplayCell { 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.content.is_empty() { - os.write_string(2, &self.content)?; + os.write_string(4, &self.content)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -2791,8 +2952,8 @@ impl ::protobuf::Message for DisplayCell { Self::descriptor_static() } - fn new() -> DisplayCell { - DisplayCell::new() + fn new() -> GridCell { + GridCell::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -2801,259 +2962,55 @@ impl ::protobuf::Message for DisplayCell { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "id", - |m: &DisplayCell| { &m.id }, - |m: &mut DisplayCell| { &mut m.id }, + |m: &GridCell| { &m.id }, + |m: &mut GridCell| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &GridCell| { &m.row_id }, + |m: &mut GridCell| { &mut m.row_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &GridCell| { &m.field_id }, + |m: &mut GridCell| { &mut m.field_id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "content", - |m: &DisplayCell| { &m.content }, - |m: &mut DisplayCell| { &mut m.content }, + |m: &GridCell| { &m.content }, + |m: &mut GridCell| { &mut m.content }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "DisplayCell", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "GridCell", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static DisplayCell { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(DisplayCell::new) + fn default_instance() -> &'static GridCell { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(GridCell::new) } } -impl ::protobuf::Clear for DisplayCell { +impl ::protobuf::Clear for GridCell { fn clear(&mut self) { self.id.clear(); + self.row_id.clear(); + self.field_id.clear(); self.content.clear(); self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for DisplayCell { +impl ::std::fmt::Debug for GridCell { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for DisplayCell { - 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 data: ::protobuf::SingularPtrField, - // 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()) - } - - // .AnyData data = 2; - - - 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()) - } -} - -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_message_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 let Some(ref v) = self.data.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 let Some(ref v) = self.data.as_ref() { - os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> 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_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "data", - |m: &RawCell| { &m.data }, - |m: &mut RawCell| { &mut m.data }, - )); - ::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.data.clear(); - 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 { +impl ::protobuf::reflect::ProtobufValue for GridCell { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -3447,37 +3404,37 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x11.RepeatedRowOrderR\trowOrders\"D\n\nGridFilter\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\"7\n\x12RepeatedGridFilter\ - \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.GridFilterR\x05items\"]\n\nFi\ + \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.GridFilterR\x05items\"G\n\nFi\ eldOrder\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x1e\n\ - \nvisibility\x18\x02\x20\x01(\x08R\nvisibility\x12\x14\n\x05width\x18\ - \x03\x20\x01(\x05R\x05width\"7\n\x12RepeatedFieldOrder\x12!\n\x05items\ - \x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"\xaf\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+\n\x0ctype_options\x18\x06\x20\x01(\ - \x0b2\x08.AnyDataR\x0btypeOptions\":\n\x07AnyData\x12\x19\n\x08type_url\ - \x18\x01\x20\x01(\tR\x07typeUrl\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\ - \x05value\"Z\n\x08RowOrder\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06g\ - ridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x1e\n\nvisibi\ - lity\x18\x03\x20\x01(\x08R\nvisibility\"3\n\x10RepeatedRowOrder\x12\x1f\ - \n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05items\"\xde\x01\n\x03Ro\ - w\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\ - \x20\x01(\tR\x06gridId\x12#\n\rmodified_time\x18\x03\x20\x01(\x03R\x0cmo\ - difiedTime\x12@\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2\x17.Row.Cell\ - ByFieldIdEntryR\rcellByFieldId\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\"H\n\x04Cell\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\"7\n\x0bDisplayCell\ - \x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x18\n\x07content\x18\x02\ - \x20\x01(\tR\x07content\"7\n\x07RawCell\x12\x0e\n\x02id\x18\x01\x20\x01(\ - \tR\x02id\x12\x1c\n\x04data\x18\x02\x20\x01(\x0b2\x08.AnyDataR\x04data\"\ - '\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*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\ + \nvisibility\x18\x02\x20\x01(\x08R\nvisibility\"7\n\x12RepeatedFieldOrde\ + r\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\x04n\ + ame\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\tfieldTyp\ + e\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06frozen\x12\x14\n\x05width\ + \x18\x06\x20\x01(\x05R\x05width\x12+\n\x0ctype_options\x18\x07\x20\x01(\ + \x0b2\x08.AnyDataR\x0btypeOptions\"-\n\rRepeatedField\x12\x1c\n\x05items\ + \x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"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\"Z\n\x08RowOrder\x12\x17\n\x07grid_id\x18\x01\x20\x01(\t\ + R\x06gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x1e\n\n\ + visibility\x18\x03\x20\x01(\x08R\nvisibility\"3\n\x10RepeatedRowOrder\ + \x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05items\"\xea\x01\ + \n\x07GridRow\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x17\n\x07gri\ + d_id\x18\x02\x20\x01(\tR\x06gridId\x12#\n\rmodified_time\x18\x03\x20\x01\ + (\x03R\x0cmodifiedTime\x12D\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2\ + \x1b.GridRow.CellByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdE\ + ntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\ + \x02\x20\x01(\x0b2\t.GridCellR\x05value:\x028\x01\"-\n\x0bRepeatedRow\ + \x12\x1e\n\x05items\x18\x01\x20\x03(\x0b2\x08.GridRowR\x05items\"f\n\x08\ + GridCell\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\x18\n\x07content\x18\x04\x20\x01(\tR\x07content\"'\n\x11\ + CreateGridPayload\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\tFieldTyp\ + e\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08Dat\ + eTime\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 d1233a3e28..352a54c5c8 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 @@ -17,7 +17,6 @@ message RepeatedGridFilter { message FieldOrder { string field_id = 1; bool visibility = 2; - int32 width = 3; } message RepeatedFieldOrder { repeated FieldOrder items = 1; @@ -28,10 +27,14 @@ message Field { string desc = 3; FieldType field_type = 4; bool frozen = 5; - AnyData type_options = 6; + int32 width = 6; + AnyData type_options = 7; +} +message RepeatedField { + repeated Field items = 1; } message AnyData { - string type_url = 1; + string type_id = 1; bytes value = 2; } message RowOrder { @@ -42,24 +45,20 @@ message RowOrder { message RepeatedRowOrder { repeated RowOrder items = 1; } -message Row { +message GridRow { string id = 1; string grid_id = 2; int64 modified_time = 3; - map cell_by_field_id = 4; + map cell_by_field_id = 4; } -message Cell { +message RepeatedRow { + repeated GridRow items = 1; +} +message GridCell { string id = 1; string row_id = 2; string field_id = 3; -} -message DisplayCell { - string id = 1; - string content = 2; -} -message RawCell { - string id = 1; - AnyData data = 2; + string content = 4; } message CreateGridPayload { string name = 1; From 67e6b091a5bfb9c5bbc6fb47eee58cb47f49cb68 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 4 Mar 2022 08:22:49 +0800 Subject: [PATCH 07/17] feat: config grid plugin --- frontend/app_flowy/lib/plugin/plugin.dart | 3 + .../lib/startup/tasks/load_plugin.dart | 2 + .../workspace/application/grid/grid_bloc.dart | 5 +- .../presentation/home/home_stack.dart | 2 +- .../presentation/plugins/blank/blank.dart | 10 +- .../presentation/plugins/grid/grid.dart | 63 + .../controller/flowy_table_selection.dart | 0 .../{ => src}/controller/grid_scroll.dart | 0 .../plugins/grid/{ => src}/grid_page.dart | 12 +- .../layout/layout.dart} | 2 +- .../layout/sizes.dart} | 0 .../widgets/content}/cell_builder.dart | 2 +- .../widgets/content}/cell_container.dart | 2 +- .../widgets/content}/cell_decoration.dart | 0 .../widgets/content}/grid_cell.dart | 2 +- .../widgets/content}/grid_row.dart | 6 +- .../widgets/footer}/grid_footer.dart | 5 +- .../widgets/header}/constants.dart | 0 .../widgets/header}/header.dart | 4 +- .../widgets/header}/header_cell.dart | 2 +- .../plugins/grid/widgets/grid_error_page.dart | 14 - .../presentation/plugins/trash/trash.dart | 10 +- .../flowy-grid-data-model/grid.pb.dart | 559 +++--- .../flowy-grid-data-model/grid.pbjson.dart | 137 +- .../rust-lib/flowy-grid/src/event_handler.rs | 10 +- .../src/entities/grid.rs | 82 +- .../src/protobuf/model/grid.rs | 1631 +++++++++++------ .../src/protobuf/proto/grid.proto | 44 +- 28 files changed, 1623 insertions(+), 986 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/{ => src}/controller/flowy_table_selection.dart (100%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/{ => src}/controller/grid_scroll.dart (100%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/{ => src}/grid_page.dart (93%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/{grid_layout.dart => src/layout/layout.dart} (93%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/{grid_sizes.dart => src/layout/sizes.dart} (100%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/{widgets/grid_content => src/widgets/content}/cell_builder.dart (84%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/{widgets/grid_content => src/widgets/content}/cell_container.dart (92%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/{widgets/grid_content => src/widgets/content}/cell_decoration.dart (100%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/{widgets/grid_content => src/widgets/content}/grid_cell.dart (96%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/{widgets/grid_content => src/widgets/content}/grid_row.dart (91%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/{widgets/grid_footer => src/widgets/footer}/grid_footer.dart (86%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/{widgets/grid_header => src/widgets/header}/constants.dart (100%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/{widgets/grid_header => src/widgets/header}/header.dart (93%) rename frontend/app_flowy/lib/workspace/presentation/plugins/grid/{widgets/grid_header => src/widgets/header}/header_cell.dart (94%) delete mode 100755 frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_error_page.dart diff --git a/frontend/app_flowy/lib/plugin/plugin.dart b/frontend/app_flowy/lib/plugin/plugin.dart index d0effa0e6d..5007e92e18 100644 --- a/frontend/app_flowy/lib/plugin/plugin.dart +++ b/frontend/app_flowy/lib/plugin/plugin.dart @@ -13,6 +13,7 @@ enum DefaultPlugin { quillEditor, blank, trash, + grid, } extension FlowyDefaultPluginExt on DefaultPlugin { @@ -24,6 +25,8 @@ extension FlowyDefaultPluginExt on DefaultPlugin { return 1; case DefaultPlugin.trash: return 2; + case DefaultPlugin.grid: + return 3; } } } diff --git a/frontend/app_flowy/lib/startup/tasks/load_plugin.dart b/frontend/app_flowy/lib/startup/tasks/load_plugin.dart index 266c6d1c09..fd4bb7e2b9 100644 --- a/frontend/app_flowy/lib/startup/tasks/load_plugin.dart +++ b/frontend/app_flowy/lib/startup/tasks/load_plugin.dart @@ -2,6 +2,7 @@ import 'package:app_flowy/plugin/plugin.dart'; import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/presentation/plugins/blank/blank.dart'; import 'package:app_flowy/workspace/presentation/plugins/doc/document.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/grid.dart'; import 'package:app_flowy/workspace/presentation/plugins/trash/trash.dart'; class PluginLoadTask extends LaunchTask { @@ -13,5 +14,6 @@ class PluginLoadTask extends LaunchTask { registerPlugin(builder: BlankPluginBuilder(), config: BlankPluginConfig()); registerPlugin(builder: TrashPluginBuilder(), config: TrashPluginConfig()); registerPlugin(builder: DocumentPluginBuilder()); + registerPlugin(builder: GridPluginBuilder(), config: GridPluginConfig()); } } 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 d8da9e9d65..40b145b8a4 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -74,7 +74,6 @@ class GridBloc extends Bloc { result.fold((repeatedRow) { final rows = repeatedRow.items; final gridInfo = GridInfo(rows: rows, fields: _fields!); - emit( state.copyWith(loadingState: GridLoadingState.finish(left(unit)), gridInfo: some(left(gridInfo))), ); @@ -116,7 +115,7 @@ class GridLoadingState with _$GridLoadingState { } class GridInfo { - List rows; + List rows; List fields; GridInfo({ @@ -139,7 +138,7 @@ class GridInfo { class RowInfo { List fields; - Map cellMap; + Map cellMap; RowInfo({ required this.fields, required this.cellMap, 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 3344b2793a..8e249ab9c5 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/home_stack.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/home_stack.dart @@ -170,7 +170,7 @@ class HomeStackManager { if (pluginType == notifier.plugin.ty) { return notifier.plugin.display.buildWidget(); } else { - return const BlankStackPage(); + return const BlankPage(); } }).toList(), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/blank/blank.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/blank/blank.dart index 6be2a788fb..598f6971f2 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/blank/blank.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/blank/blank.dart @@ -45,20 +45,20 @@ class BlankPagePluginDisplay extends PluginDisplay { Widget get leftBarItem => FlowyText.medium(LocaleKeys.blankPageTitle.tr(), fontSize: 12); @override - Widget buildWidget() => const BlankStackPage(); + Widget buildWidget() => const BlankPage(); @override List get navigationItems => [this]; } -class BlankStackPage extends StatefulWidget { - const BlankStackPage({Key? key}) : super(key: key); +class BlankPage extends StatefulWidget { + const BlankPage({Key? key}) : super(key: key); @override - State createState() => _BlankStackPageState(); + State createState() => _BlankPageState(); } -class _BlankStackPageState extends State { +class _BlankPageState extends State { @override Widget build(BuildContext context) { return SizedBox.expand( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart new file mode 100644 index 0000000000..0fca5db0c7 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart @@ -0,0 +1,63 @@ +import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; +import 'package:app_flowy/plugin/plugin.dart'; +import 'package:flutter/material.dart'; + +import 'src/grid_page.dart'; + +class GridPluginBuilder extends PluginBuilder { + @override + Plugin build(dynamic data) { + if (data is View) { + return GridPlugin(pluginType: pluginType, view: data); + } else { + throw FlowyPluginException.invalidData; + } + } + + @override + String get menuName => "Table"; + + @override + PluginType get pluginType => DefaultPlugin.grid.type(); +} + +class GridPluginConfig implements PluginConfig { + @override + bool get creatable => true; +} + +class GridPlugin extends Plugin { + final View _view; + final PluginType _pluginType; + + GridPlugin({ + required View view, + required PluginType pluginType, + }) : _pluginType = pluginType, + _view = view; + + @override + PluginDisplay get display => GridPluginDisplay(view: _view); + + @override + PluginId get id => _view.id; + + @override + PluginType get ty => _pluginType; +} + +class GridPluginDisplay extends PluginDisplay { + final View _view; + GridPluginDisplay({required View view, Key? key}) : _view = view; + + @override + Widget get leftBarItem => const FlowyText.medium("Grid demo", fontSize: 12); + + @override + Widget buildWidget() => GridPage(view: _view); + + @override + List get navigationItems => [this]; +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/controller/flowy_table_selection.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/controller/flowy_table_selection.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/controller/flowy_table_selection.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/controller/flowy_table_selection.dart diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/controller/grid_scroll.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/controller/grid_scroll.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/controller/grid_scroll.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/controller/grid_scroll.dart diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart similarity index 93% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_page.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart index 6b72af2aa5..33b8c94fa5 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart @@ -8,14 +8,14 @@ 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:flutter_bloc/flutter_bloc.dart'; import 'package:flutter/material.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/controller/grid_scroll.dart'; import 'package:styled_widget/styled_widget.dart'; -import 'grid_layout.dart'; -import 'grid_sizes.dart'; -import 'widgets/grid_content/grid_row.dart'; -import 'widgets/grid_footer/grid_footer.dart'; -import 'widgets/grid_header/header.dart'; +import 'controller/grid_scroll.dart'; +import 'layout/layout.dart'; +import 'layout/sizes.dart'; +import 'widgets/content/grid_row.dart'; +import 'widgets/footer/grid_footer.dart'; +import 'widgets/header/header.dart'; class GridPage extends StatefulWidget { final View view; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_layout.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart similarity index 93% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_layout.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart index 0daeacbb33..a44ad20d39 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_layout.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart @@ -1,6 +1,6 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; -import 'grid_sizes.dart'; +import 'sizes.dart'; class GridLayout { static double headerWidth(List fields) { diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_sizes.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid_sizes.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/sizes.dart diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart similarity index 84% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_builder.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart index 5ff1922835..1c02664c86 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_builder.dart @@ -2,7 +2,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'grid_cell.dart'; class GridCellBuilder { - static GridCellWidget buildCell(Field? field, GridCell? cell) { + static GridCellWidget buildCell(Field? field, Cell? cell) { if (field == null || cell == null) { return const BlankCell(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart similarity index 92% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_container.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart index 1ba7c1f009..edd0de5076 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_container.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/presentation/plugins/grid/grid_sizes.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 'cell_decoration.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_decoration.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_decoration.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/cell_decoration.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/cell_decoration.dart diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart similarity index 96% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_cell.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart index 93701e1ded..00e6fad6af 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_cell.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/presentation/plugins/grid/grid_sizes.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'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart similarity index 91% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_row.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart index 247f9fc525..4d5da03423 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_content/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/content/grid_row.dart @@ -1,6 +1,6 @@ import 'package:app_flowy/workspace/application/grid/grid_bloc.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/grid_sizes.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.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:flutter/material.dart'; import 'cell_builder.dart'; import 'cell_container.dart'; @@ -9,7 +9,7 @@ import 'grid_cell.dart'; class GridRowContext { final RepeatedFieldOrder fieldOrders; final Map fieldById; - final Map cellByFieldId; + final Map cellByFieldId; GridRowContext(this.fieldOrders, this.fieldById, this.cellByFieldId); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_footer/grid_footer.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart similarity index 86% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_footer/grid_footer.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart index b5ccee4892..cdbb0d6e51 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_footer/grid_footer.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/footer/grid_footer.dart @@ -1,8 +1,9 @@ -import 'package:app_flowy/workspace/presentation/plugins/grid/grid_sizes.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/widgets/grid_content/cell_decoration.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 '../content/cell_decoration.dart'; + class GridFooter extends StatelessWidget { final VoidCallback? onAddRow; const GridFooter({Key? key, required this.onAddRow}) : super(key: key); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/constants.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/constants.dart similarity index 100% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/constants.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/constants.dart diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart similarity index 93% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart index 51bceb239a..9f894f8ee5 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header.dart @@ -1,5 +1,5 @@ -import 'package:app_flowy/workspace/presentation/plugins/grid/grid_sizes.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.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:flutter/material.dart'; import 'header_cell.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart similarity index 94% rename from frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header_cell.dart rename to frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart index 8fbe34fa2b..4148f1e041 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_header/header_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/header_cell.dart @@ -1,4 +1,4 @@ -import 'package:app_flowy/workspace/presentation/plugins/grid/grid_sizes.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'; import 'package:flutter/material.dart'; import 'constants.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_error_page.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_error_page.dart deleted file mode 100755 index 92973a05b3..0000000000 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/widgets/grid_error_page.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -class GridUnknownError extends StatelessWidget { - const GridUnknownError({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - child: Center( - child: CircularProgressIndicator(), - ), - ); - } -} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/trash/trash.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/trash/trash.dart index 4f9ef4c911..e74289d982 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/trash/trash.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/trash/trash.dart @@ -65,20 +65,20 @@ class TrashPluginDisplay extends PluginDisplay { Widget? get rightBarItem => null; @override - Widget buildWidget() => const TrashStackPage(key: ValueKey('TrashStackPage')); + Widget buildWidget() => const TrashPage(key: ValueKey('TrashPage')); @override List get navigationItems => [this]; } -class TrashStackPage extends StatefulWidget { - const TrashStackPage({Key? key}) : super(key: key); +class TrashPage extends StatefulWidget { + const TrashPage({Key? key}) : super(key: key); @override - State createState() => _TrashStackPageState(); + State createState() => _TrashPageState(); } -class _TrashStackPageState extends State { +class _TrashPageState extends State { final ScrollController _scrollController = ScrollController(); @override Widget build(BuildContext context) { 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 2d8aeace2c..ba0b827df8 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 @@ -7,7 +7,6 @@ import 'dart:core' as $core; -import 'package:fixnum/fixnum.dart' as $fixnum; import 'package:protobuf/protobuf.dart' as $pb; import 'grid.pbenum.dart'; @@ -16,8 +15,8 @@ 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') ? '' : 'gridId') - ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'filters', subBuilder: RepeatedGridFilter.create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'filters', subBuilder: RepeatedFilter.create) ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', subBuilder: RepeatedFieldOrder.create) ..aOM(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', subBuilder: RepeatedRowOrder.create) ..hasRequiredFields = false @@ -25,14 +24,14 @@ class Grid extends $pb.GeneratedMessage { Grid._() : super(); factory Grid({ - $core.String? gridId, - RepeatedGridFilter? filters, + $core.String? id, + RepeatedFilter? filters, RepeatedFieldOrder? fieldOrders, RepeatedRowOrder? rowOrders, }) { final _result = create(); - if (gridId != null) { - _result.gridId = gridId; + if (id != null) { + _result.id = id; } if (filters != null) { _result.filters = filters; @@ -67,24 +66,24 @@ class Grid extends $pb.GeneratedMessage { static Grid? _defaultInstance; @$pb.TagNumber(1) - $core.String get gridId => $_getSZ(0); + $core.String get id => $_getSZ(0); @$pb.TagNumber(1) - set gridId($core.String v) { $_setString(0, v); } + set id($core.String v) { $_setString(0, v); } @$pb.TagNumber(1) - $core.bool hasGridId() => $_has(0); + $core.bool hasId() => $_has(0); @$pb.TagNumber(1) - void clearGridId() => clearField(1); + void clearId() => clearField(1); @$pb.TagNumber(2) - RepeatedGridFilter get filters => $_getN(1); + RepeatedFilter get filters => $_getN(1); @$pb.TagNumber(2) - set filters(RepeatedGridFilter v) { setField(2, v); } + set filters(RepeatedFilter v) { setField(2, v); } @$pb.TagNumber(2) $core.bool hasFilters() => $_has(1); @$pb.TagNumber(2) void clearFilters() => clearField(2); @$pb.TagNumber(2) - RepeatedGridFilter ensureFilters() => $_ensure(1); + RepeatedFilter ensureFilters() => $_ensure(1); @$pb.TagNumber(3) RepeatedFieldOrder get fieldOrders => $_getN(2); @@ -109,122 +108,6 @@ class Grid extends $pb.GeneratedMessage { RepeatedRowOrder ensureRowOrders() => $_ensure(3); } -class GridFilter extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridFilter', 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') - ..hasRequiredFields = false - ; - - GridFilter._() : super(); - factory GridFilter({ - $core.String? id, - $core.String? name, - $core.String? desc, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (name != null) { - _result.name = name; - } - if (desc != null) { - _result.desc = desc; - } - return _result; - } - factory GridFilter.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GridFilter.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') - GridFilter clone() => GridFilter()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - GridFilter copyWith(void Function(GridFilter) updates) => super.copyWith((message) => updates(message as GridFilter)) as GridFilter; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static GridFilter create() => GridFilter._(); - GridFilter createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static GridFilter getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GridFilter? _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); -} - -class RepeatedGridFilter extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedGridFilter', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: GridFilter.create) - ..hasRequiredFields = false - ; - - RepeatedGridFilter._() : super(); - factory RepeatedGridFilter({ - $core.Iterable? items, - }) { - final _result = create(); - if (items != null) { - _result.items.addAll(items); - } - return _result; - } - factory RepeatedGridFilter.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RepeatedGridFilter.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') - RepeatedGridFilter clone() => RepeatedGridFilter()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RepeatedGridFilter copyWith(void Function(RepeatedGridFilter) updates) => super.copyWith((message) => updates(message as RepeatedGridFilter)) as RepeatedGridFilter; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RepeatedGridFilter create() => RepeatedGridFilter._(); - RepeatedGridFilter createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RepeatedGridFilter getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RepeatedGridFilter? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get items => $_getList(0); -} - 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') @@ -678,21 +561,19 @@ class RepeatedRowOrder extends $pb.GeneratedMessage { $core.List get items => $_getList(0); } -class GridRow extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridRow', createEmptyInstance: create) +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') - ..aInt64(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'modifiedTime') - ..m<$core.String, GridCell>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'GridRow.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: GridCell.create) + ..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) ..hasRequiredFields = false ; - GridRow._() : super(); - factory GridRow({ + RawRow._() : super(); + factory RawRow({ $core.String? id, $core.String? gridId, - $fixnum.Int64? modifiedTime, - $core.Map<$core.String, GridCell>? cellByFieldId, + $core.Map<$core.String, RawCell>? cellByFieldId, }) { final _result = create(); if (id != null) { @@ -701,34 +582,31 @@ class GridRow extends $pb.GeneratedMessage { if (gridId != null) { _result.gridId = gridId; } - if (modifiedTime != null) { - _result.modifiedTime = modifiedTime; - } if (cellByFieldId != null) { _result.cellByFieldId.addAll(cellByFieldId); } return _result; } - factory GridRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GridRow.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + 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') - GridRow clone() => GridRow()..mergeFromMessage(this); + 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') - GridRow copyWith(void Function(GridRow) updates) => super.copyWith((message) => updates(message as GridRow)) as GridRow; // ignore: deprecated_member_use + 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 GridRow create() => GridRow._(); - GridRow createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static RawRow create() => RawRow._(); + RawRow createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static GridRow getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GridRow? _defaultInstance; + static RawRow getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RawRow? _defaultInstance; @$pb.TagNumber(1) $core.String get id => $_getSZ(0); @@ -749,74 +627,24 @@ class GridRow extends $pb.GeneratedMessage { void clearGridId() => clearField(2); @$pb.TagNumber(3) - $fixnum.Int64 get modifiedTime => $_getI64(2); - @$pb.TagNumber(3) - set modifiedTime($fixnum.Int64 v) { $_setInt64(2, v); } - @$pb.TagNumber(3) - $core.bool hasModifiedTime() => $_has(2); - @$pb.TagNumber(3) - void clearModifiedTime() => clearField(3); - - @$pb.TagNumber(4) - $core.Map<$core.String, GridCell> get cellByFieldId => $_getMap(3); + $core.Map<$core.String, RawCell> get cellByFieldId => $_getMap(2); } -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: GridRow.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 GridCell extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridCell', createEmptyInstance: create) +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') - ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'content') + ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') ..hasRequiredFields = false ; - GridCell._() : super(); - factory GridCell({ + RawCell._() : super(); + factory RawCell({ $core.String? id, $core.String? rowId, $core.String? fieldId, - $core.String? content, + $core.String? data, }) { final _result = create(); if (id != null) { @@ -828,31 +656,31 @@ class GridCell extends $pb.GeneratedMessage { if (fieldId != null) { _result.fieldId = fieldId; } - if (content != null) { - _result.content = content; + if (data != null) { + _result.data = data; } return _result; } - factory GridCell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GridCell.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + 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') - GridCell clone() => GridCell()..mergeFromMessage(this); + 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') - GridCell copyWith(void Function(GridCell) updates) => super.copyWith((message) => updates(message as GridCell)) as GridCell; // ignore: deprecated_member_use + 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 GridCell create() => GridCell._(); - GridCell createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); + static RawCell create() => RawCell._(); + RawCell createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); @$core.pragma('dart2js:noInline') - static GridCell getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GridCell? _defaultInstance; + static RawCell getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RawCell? _defaultInstance; @$pb.TagNumber(1) $core.String get id => $_getSZ(0); @@ -882,13 +710,184 @@ class GridCell extends $pb.GeneratedMessage { void clearFieldId() => clearField(3); @$pb.TagNumber(4) - $core.String get content => $_getSZ(3); + $core.String get data => $_getSZ(3); @$pb.TagNumber(4) - set content($core.String v) { $_setString(3, v); } + set data($core.String v) { $_setString(3, v); } @$pb.TagNumber(4) - $core.bool hasContent() => $_has(3); + $core.bool hasData() => $_has(3); @$pb.TagNumber(4) - void clearContent() => clearField(4); + void clearData() => clearField(4); +} + +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') + ..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) + ..hasRequiredFields = false + ; + + Row._() : super(); + factory Row({ + $core.String? id, + $core.Map<$core.String, Cell>? cellByFieldId, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (cellByFieldId != null) { + _result.cellByFieldId.addAll(cellByFieldId); + } + return _result; + } + factory Row.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Row.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') + Row clone() => Row()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Row copyWith(void Function(Row) updates) => super.copyWith((message) => updates(message as Row)) as Row; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Row create() => Row._(); + Row createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Row getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Row? _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.Map<$core.String, Cell> get cellByFieldId => $_getMap(1); +} + +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') + ..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; + } + if (content != null) { + _result.content = content; + } + return _result; + } + factory Cell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Cell.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') + Cell clone() => Cell()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Cell copyWith(void Function(Cell) updates) => super.copyWith((message) => updates(message as Cell)) as Cell; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Cell create() => Cell._(); + Cell createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Cell getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Cell? _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 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 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); } class CreateGridPayload extends $pb.GeneratedMessage { @@ -985,3 +984,119 @@ class GridId extends $pb.GeneratedMessage { void clearValue() => clearField(1); } +class Filter extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Filter', 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') + ..hasRequiredFields = false + ; + + Filter._() : super(); + factory Filter({ + $core.String? id, + $core.String? name, + $core.String? desc, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (name != null) { + _result.name = name; + } + if (desc != null) { + _result.desc = desc; + } + return _result; + } + factory Filter.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Filter.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') + Filter clone() => Filter()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Filter copyWith(void Function(Filter) updates) => super.copyWith((message) => updates(message as Filter)) as Filter; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Filter create() => Filter._(); + Filter createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Filter getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Filter? _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); +} + +class RepeatedFilter extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedFilter', createEmptyInstance: create) + ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Filter.create) + ..hasRequiredFields = false + ; + + RepeatedFilter._() : super(); + factory RepeatedFilter({ + $core.Iterable? items, + }) { + final _result = create(); + if (items != null) { + _result.items.addAll(items); + } + return _result; + } + factory RepeatedFilter.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RepeatedFilter.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') + RepeatedFilter clone() => RepeatedFilter()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RepeatedFilter copyWith(void Function(RepeatedFilter) updates) => super.copyWith((message) => updates(message as RepeatedFilter)) as RepeatedFilter; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RepeatedFilter create() => RepeatedFilter._(); + RepeatedFilter createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static RepeatedFilter getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static RepeatedFilter? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get items => $_getList(0); +} + 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 bfbd6266da..205acfd611 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 @@ -27,37 +27,15 @@ final $typed_data.Uint8List fieldTypeDescriptor = $convert.base64Decode('CglGaWV const Grid$json = const { '1': 'Grid', '2': const [ - const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'filters', '3': 2, '4': 1, '5': 11, '6': '.RepeatedGridFilter', '10': 'filters'}, + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'filters', '3': 2, '4': 1, '5': 11, '6': '.RepeatedFilter', '10': 'filters'}, const {'1': 'field_orders', '3': 3, '4': 1, '5': 11, '6': '.RepeatedFieldOrder', '10': 'fieldOrders'}, const {'1': 'row_orders', '3': 4, '4': 1, '5': 11, '6': '.RepeatedRowOrder', '10': 'rowOrders'}, ], }; /// Descriptor for `Grid`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBItCgdmaWx0ZXJzGAIgASgLMhMuUmVwZWF0ZWRHcmlkRmlsdGVyUgdmaWx0ZXJzEjYKDGZpZWxkX29yZGVycxgDIAEoCzITLlJlcGVhdGVkRmllbGRPcmRlclILZmllbGRPcmRlcnMSMAoKcm93X29yZGVycxgEIAEoCzIRLlJlcGVhdGVkUm93T3JkZXJSCXJvd09yZGVycw=='); -@$core.Deprecated('Use gridFilterDescriptor instead') -const GridFilter$json = const { - '1': 'GridFilter', - '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'}, - ], -}; - -/// Descriptor for `GridFilter`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridFilterDescriptor = $convert.base64Decode('CgpHcmlkRmlsdGVyEg4KAmlkGAEgASgJUgJpZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2M='); -@$core.Deprecated('Use repeatedGridFilterDescriptor instead') -const RepeatedGridFilter$json = const { - '1': 'RepeatedGridFilter', - '2': const [ - const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.GridFilter', '10': 'items'}, - ], -}; - -/// Descriptor for `RepeatedGridFilter`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List repeatedGridFilterDescriptor = $convert.base64Decode('ChJSZXBlYXRlZEdyaWRGaWx0ZXISIQoFaXRlbXMYASADKAsyCy5HcmlkRmlsdGVyUgVpdGVtcw=='); +final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIpCgdmaWx0ZXJzGAIgASgLMg8uUmVwZWF0ZWRGaWx0ZXJSB2ZpbHRlcnMSNgoMZmllbGRfb3JkZXJzGAMgASgLMhMuUmVwZWF0ZWRGaWVsZE9yZGVyUgtmaWVsZE9yZGVycxIwCgpyb3dfb3JkZXJzGAQgASgLMhEuUmVwZWF0ZWRSb3dPcmRlclIJcm93T3JkZXJz'); @$core.Deprecated('Use fieldOrderDescriptor instead') const FieldOrder$json = const { '1': 'FieldOrder', @@ -138,53 +116,86 @@ const RepeatedRowOrder$json = const { /// Descriptor for `RepeatedRowOrder`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List repeatedRowOrderDescriptor = $convert.base64Decode('ChBSZXBlYXRlZFJvd09yZGVyEh8KBWl0ZW1zGAEgAygLMgkuUm93T3JkZXJSBWl0ZW1z'); -@$core.Deprecated('Use gridRowDescriptor instead') -const GridRow$json = const { - '1': 'GridRow', +@$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': 'modified_time', '3': 3, '4': 1, '5': 3, '10': 'modifiedTime'}, - const {'1': 'cell_by_field_id', '3': 4, '4': 3, '5': 11, '6': '.GridRow.CellByFieldIdEntry', '10': 'cellByFieldId'}, + const {'1': 'cell_by_field_id', '3': 3, '4': 3, '5': 11, '6': '.RawRow.CellByFieldIdEntry', '10': 'cellByFieldId'}, ], - '3': const [GridRow_CellByFieldIdEntry$json], + '3': const [RawRow_CellByFieldIdEntry$json], }; -@$core.Deprecated('Use gridRowDescriptor instead') -const GridRow_CellByFieldIdEntry$json = const { +@$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': '.GridCell', '10': 'value'}, + const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.RawCell', '10': 'value'}, ], '7': const {'7': true}, }; -/// Descriptor for `GridRow`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridRowDescriptor = $convert.base64Decode('CgdHcmlkUm93Eg4KAmlkGAEgASgJUgJpZBIXCgdncmlkX2lkGAIgASgJUgZncmlkSWQSIwoNbW9kaWZpZWRfdGltZRgDIAEoA1IMbW9kaWZpZWRUaW1lEkQKEGNlbGxfYnlfZmllbGRfaWQYBCADKAsyGy5HcmlkUm93LkNlbGxCeUZpZWxkSWRFbnRyeVINY2VsbEJ5RmllbGRJZBpLChJDZWxsQnlGaWVsZElkRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSHwoFdmFsdWUYAiABKAsyCS5HcmlkQ2VsbFIFdmFsdWU6AjgB'); -@$core.Deprecated('Use repeatedRowDescriptor instead') -const RepeatedRow$json = const { - '1': 'RepeatedRow', - '2': const [ - const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.GridRow', '10': 'items'}, - ], -}; - -/// Descriptor for `RepeatedRow`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List repeatedRowDescriptor = $convert.base64Decode('CgtSZXBlYXRlZFJvdxIeCgVpdGVtcxgBIAMoCzIILkdyaWRSb3dSBWl0ZW1z'); -@$core.Deprecated('Use gridCellDescriptor instead') -const GridCell$json = const { - '1': 'GridCell', +/// Descriptor for `RawRow`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List rawRowDescriptor = $convert.base64Decode('CgZSYXdSb3cSDgoCaWQYASABKAlSAmlkEhcKB2dyaWRfaWQYAiABKAlSBmdyaWRJZBJDChBjZWxsX2J5X2ZpZWxkX2lkGAMgAygLMhouUmF3Um93LkNlbGxCeUZpZWxkSWRFbnRyeVINY2VsbEJ5RmllbGRJZBpKChJDZWxsQnlGaWVsZElkRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSHgoFdmFsdWUYAiABKAsyCC5SYXdDZWxsUgV2YWx1ZToCOAE='); +@$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': 'content', '3': 4, '4': 1, '5': 9, '10': 'content'}, + const {'1': 'data', '3': 4, '4': 1, '5': 9, '10': 'data'}, ], }; -/// Descriptor for `GridCell`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridCellDescriptor = $convert.base64Decode('CghHcmlkQ2VsbBIOCgJpZBgBIAEoCVICaWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIZCghmaWVsZF9pZBgDIAEoCVIHZmllbGRJZBIYCgdjb250ZW50GAQgASgJUgdjb250ZW50'); +/// Descriptor for `RawCell`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List rawCellDescriptor = $convert.base64Decode('CgdSYXdDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhIKBGRhdGEYBCABKAlSBGRhdGE='); +@$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', + '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'}, + ], + '3': const [Row_CellByFieldIdEntry$json], +}; + +@$core.Deprecated('Use rowDescriptor instead') +const Row_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': '.Cell', '10': 'value'}, + ], + '7': const {'7': true}, +}; + +/// Descriptor for `Row`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List rowDescriptor = $convert.base64Decode('CgNSb3cSDgoCaWQYASABKAlSAmlkEkAKEGNlbGxfYnlfZmllbGRfaWQYAiADKAsyFy5Sb3cuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkGkcKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIbCgV2YWx1ZRgCIAEoCzIFLkNlbGxSBXZhbHVlOgI4AQ=='); +@$core.Deprecated('Use cellDescriptor instead') +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'}, + ], +}; + +/// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEg4KAmlkGAEgASgJUgJpZBIZCghmaWVsZF9pZBgCIAEoCVIHZmllbGRJZBIYCgdjb250ZW50GAMgASgJUgdjb250ZW50'); @$core.Deprecated('Use createGridPayloadDescriptor instead') const CreateGridPayload$json = const { '1': 'CreateGridPayload', @@ -205,3 +216,25 @@ const GridId$json = const { /// Descriptor for `GridId`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridIdDescriptor = $convert.base64Decode('CgZHcmlkSWQSFAoFdmFsdWUYASABKAlSBXZhbHVl'); +@$core.Deprecated('Use filterDescriptor instead') +const Filter$json = const { + '1': 'Filter', + '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'}, + ], +}; + +/// Descriptor for `Filter`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List filterDescriptor = $convert.base64Decode('CgZGaWx0ZXISDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYw=='); +@$core.Deprecated('Use repeatedFilterDescriptor instead') +const RepeatedFilter$json = const { + '1': 'RepeatedFilter', + '2': const [ + const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Filter', '10': 'items'}, + ], +}; + +/// Descriptor for `RepeatedFilter`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List repeatedFilterDescriptor = $convert.base64Decode('Cg5SZXBlYXRlZEZpbHRlchIdCgVpdGVtcxgBIAMoCzIHLkZpbHRlclIFaXRlbXM='); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 765da724d5..600f55ab1a 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::controller::GridManager; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ - CreateGridPayload, Grid, GridId, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, + CreateGridPayload, Grid, GridId, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, }; use lib_dispatch::prelude::{AppData, Data, DataResult}; use std::sync::Arc; @@ -28,7 +28,7 @@ pub(crate) async fn open_grid_handler( pub(crate) async fn get_rows_handler( data: Data, controller: AppData>, -) -> DataResult { +) -> DataResult { let row_orders: RepeatedRowOrder = data.into_inner(); todo!() @@ -38,7 +38,7 @@ pub(crate) async fn get_rows_handler( pub(crate) async fn get_fields_handler( data: Data, controller: AppData>, -) -> DataResult { +) -> DataResult { let field_orders: RepeatedFieldOrder = data.into_inner(); todo!() @@ -48,8 +48,8 @@ pub(crate) async fn get_fields_handler( pub(crate) async fn create_row_handler( data: Data, controller: AppData>, -) -> DataResult { +) -> Result<(), FlowyError> { let id: GridId = data.into_inner(); - todo!() + Ok(()) } 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 03e738faee..034f823fd2 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -6,10 +6,10 @@ use strum_macros::{Display, EnumIter, EnumString}; #[derive(Debug, Default, ProtoBuf)] pub struct Grid { #[pb(index = 1)] - pub grid_id: String, + pub id: String, #[pb(index = 2)] - pub filters: RepeatedGridFilter, + pub filters: RepeatedFilter, #[pb(index = 3)] pub field_orders: RepeatedFieldOrder, @@ -18,24 +18,6 @@ pub struct Grid { pub row_orders: RepeatedRowOrder, } -#[derive(Debug, Default, ProtoBuf)] -pub struct GridFilter { - #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub name: String, - - #[pb(index = 3)] - pub desc: String, -} - -#[derive(Debug, Default, ProtoBuf)] -pub struct RepeatedGridFilter { - #[pb(index = 1)] - pub items: Vec, -} - #[derive(Debug, Default, ProtoBuf)] pub struct FieldOrder { #[pb(index = 1)] @@ -167,7 +149,7 @@ pub struct RepeatedRowOrder { } #[derive(Debug, Default, ProtoBuf)] -pub struct GridRow { +pub struct RawRow { #[pb(index = 1)] pub id: String, @@ -175,20 +157,11 @@ pub struct GridRow { pub grid_id: String, #[pb(index = 3)] - pub modified_time: i64, - - #[pb(index = 4)] - pub cell_by_field_id: HashMap, + pub cell_by_field_id: HashMap, } #[derive(Debug, Default, ProtoBuf)] -pub struct RepeatedRow { - #[pb(index = 1)] - pub items: Vec, -} - -#[derive(Debug, Default, ProtoBuf)] -pub struct GridCell { +pub struct RawCell { #[pb(index = 1)] pub id: String, @@ -199,6 +172,33 @@ pub struct GridCell { pub field_id: String, #[pb(index = 4)] + pub data: String, +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct RepeatedRow { + #[pb(index = 1)] + pub items: Vec, +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct Row { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub cell_by_field_id: HashMap, +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct Cell { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub field_id: String, + + #[pb(index = 3)] pub content: String, } @@ -213,3 +213,21 @@ pub struct GridId { #[pb(index = 1)] pub value: String, } + +#[derive(Debug, Default, ProtoBuf)] +pub struct Filter { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub name: String, + + #[pb(index = 3)] + pub desc: String, +} + +#[derive(Debug, Default, ProtoBuf)] +pub struct RepeatedFilter { + #[pb(index = 1)] + pub items: Vec, +} diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index 820ac7404c..b644b4fd87 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 @@ -26,8 +26,8 @@ #[derive(PartialEq,Clone,Default)] pub struct Grid { // message fields - pub grid_id: ::std::string::String, - pub filters: ::protobuf::SingularPtrField, + pub id: ::std::string::String, + pub filters: ::protobuf::SingularPtrField, pub field_orders: ::protobuf::SingularPtrField, pub row_orders: ::protobuf::SingularPtrField, // special fields @@ -46,37 +46,37 @@ impl Grid { ::std::default::Default::default() } - // string grid_id = 1; + // string id = 1; - pub fn get_grid_id(&self) -> &str { - &self.grid_id + pub fn get_id(&self) -> &str { + &self.id } - pub fn clear_grid_id(&mut self) { - self.grid_id.clear(); + pub fn clear_id(&mut self) { + self.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_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_grid_id(&mut self) -> &mut ::std::string::String { - &mut self.grid_id + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.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_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) } - // .RepeatedGridFilter filters = 2; + // .RepeatedFilter filters = 2; - pub fn get_filters(&self) -> &RepeatedGridFilter { - self.filters.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_filters(&self) -> &RepeatedFilter { + self.filters.as_ref().unwrap_or_else(|| ::default_instance()) } pub fn clear_filters(&mut self) { self.filters.clear(); @@ -87,13 +87,13 @@ impl Grid { } // Param is passed by value, moved - pub fn set_filters(&mut self, v: RepeatedGridFilter) { + pub fn set_filters(&mut self, v: RepeatedFilter) { self.filters = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_filters(&mut self) -> &mut RepeatedGridFilter { + pub fn mut_filters(&mut self) -> &mut RepeatedFilter { if self.filters.is_none() { self.filters.set_default(); } @@ -101,8 +101,8 @@ impl Grid { } // Take field - pub fn take_filters(&mut self) -> RepeatedGridFilter { - self.filters.take().unwrap_or_else(|| RepeatedGridFilter::new()) + pub fn take_filters(&mut self) -> RepeatedFilter { + self.filters.take().unwrap_or_else(|| RepeatedFilter::new()) } // .RepeatedFieldOrder field_orders = 3; @@ -197,7 +197,7 @@ impl ::protobuf::Message for Grid { 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)?; + ::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.filters)?; @@ -220,8 +220,8 @@ impl ::protobuf::Message for Grid { #[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.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); } if let Some(ref v) = self.filters.as_ref() { let len = v.compute_size(); @@ -241,8 +241,8 @@ impl ::protobuf::Message for Grid { } 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.id.is_empty() { + os.write_string(1, &self.id)?; } if let Some(ref v) = self.filters.as_ref() { os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; @@ -298,11 +298,11 @@ impl ::protobuf::Message for Grid { descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "grid_id", - |m: &Grid| { &m.grid_id }, - |m: &mut Grid| { &mut m.grid_id }, + "id", + |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_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "filters", |m: &Grid| { &m.filters }, |m: &mut Grid| { &mut m.filters }, @@ -333,7 +333,7 @@ impl ::protobuf::Message for Grid { impl ::protobuf::Clear for Grid { fn clear(&mut self) { - self.grid_id.clear(); + self.id.clear(); self.filters.clear(); self.field_orders.clear(); self.row_orders.clear(); @@ -353,415 +353,6 @@ impl ::protobuf::reflect::ProtobufValue for Grid { } } -#[derive(PartialEq,Clone,Default)] -pub struct GridFilter { - // message fields - pub id: ::std::string::String, - pub name: ::std::string::String, - pub desc: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a GridFilter { - fn default() -> &'a GridFilter { - ::default_instance() - } -} - -impl GridFilter { - pub fn new() -> GridFilter { - ::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()) - } -} - -impl ::protobuf::Message for GridFilter { - 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)?; - }, - _ => { - ::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); - } - 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)?; - } - 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() -> GridFilter { - GridFilter::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: &GridFilter| { &m.id }, - |m: &mut GridFilter| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "name", - |m: &GridFilter| { &m.name }, - |m: &mut GridFilter| { &mut m.name }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "desc", - |m: &GridFilter| { &m.desc }, - |m: &mut GridFilter| { &mut m.desc }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GridFilter", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static GridFilter { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GridFilter::new) - } -} - -impl ::protobuf::Clear for GridFilter { - fn clear(&mut self) { - self.id.clear(); - self.name.clear(); - self.desc.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for GridFilter { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for GridFilter { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct RepeatedGridFilter { - // 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 RepeatedGridFilter { - fn default() -> &'a RepeatedGridFilter { - ::default_instance() - } -} - -impl RepeatedGridFilter { - pub fn new() -> RepeatedGridFilter { - ::std::default::Default::default() - } - - // repeated .GridFilter items = 1; - - - pub fn get_items(&self) -> &[GridFilter] { - &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 RepeatedGridFilter { - 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() -> RepeatedGridFilter { - RepeatedGridFilter::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: &RepeatedGridFilter| { &m.items }, - |m: &mut RepeatedGridFilter| { &mut m.items }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RepeatedGridFilter", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RepeatedGridFilter { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RepeatedGridFilter::new) - } -} - -impl ::protobuf::Clear for RepeatedGridFilter { - fn clear(&mut self) { - self.items.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RepeatedGridFilter { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RepeatedGridFilter { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct FieldOrder { // message fields @@ -2293,25 +1884,24 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedRowOrder { } #[derive(PartialEq,Clone,Default)] -pub struct GridRow { +pub struct RawRow { // message fields pub id: ::std::string::String, pub grid_id: ::std::string::String, - pub modified_time: i64, - pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, GridCell>, + pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, RawCell>, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a GridRow { - fn default() -> &'a GridRow { - ::default_instance() +impl<'a> ::std::default::Default for &'a RawRow { + fn default() -> &'a RawRow { + ::default_instance() } } -impl GridRow { - pub fn new() -> GridRow { +impl RawRow { + pub fn new() -> RawRow { ::std::default::Default::default() } @@ -2367,25 +1957,10 @@ impl GridRow { ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) } - // int64 modified_time = 3; + // repeated .RawRow.CellByFieldIdEntry cell_by_field_id = 3; - pub fn get_modified_time(&self) -> i64 { - self.modified_time - } - pub fn clear_modified_time(&mut self) { - self.modified_time = 0; - } - - // Param is passed by value, moved - pub fn set_modified_time(&mut self, v: i64) { - self.modified_time = v; - } - - // repeated .GridRow.CellByFieldIdEntry cell_by_field_id = 4; - - - pub fn get_cell_by_field_id(&self) -> &::std::collections::HashMap<::std::string::String, GridCell> { + 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) { @@ -2393,22 +1968,22 @@ impl GridRow { } // Param is passed by value, moved - pub fn set_cell_by_field_id(&mut self, v: ::std::collections::HashMap<::std::string::String, GridCell>) { + 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, GridCell> { + 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, GridCell> { + 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()) } } -impl ::protobuf::Message for GridRow { +impl ::protobuf::Message for RawRow { fn is_initialized(&self) -> bool { true } @@ -2424,14 +1999,7 @@ impl ::protobuf::Message for GridRow { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_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_int64()?; - self.modified_time = tmp; - }, - 4 => { - ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.cell_by_field_id)?; + ::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())?; @@ -2451,10 +2019,7 @@ impl ::protobuf::Message for GridRow { if !self.grid_id.is_empty() { my_size += ::protobuf::rt::string_size(2, &self.grid_id); } - if self.modified_time != 0 { - my_size += ::protobuf::rt::value_size(3, self.modified_time, ::protobuf::wire_format::WireTypeVarint); - } - my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(4, &self.cell_by_field_id); + my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id); my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -2467,10 +2032,7 @@ impl ::protobuf::Message for GridRow { if !self.grid_id.is_empty() { os.write_string(2, &self.grid_id)?; } - if self.modified_time != 0 { - os.write_int64(3, self.modified_time)?; - } - ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(4, &self.cell_by_field_id, os)?; + ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(3, &self.cell_by_field_id, os)?; os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -2501,8 +2063,8 @@ impl ::protobuf::Message for GridRow { Self::descriptor_static() } - fn new() -> GridRow { - GridRow::new() + fn new() -> RawRow { + RawRow::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -2511,55 +2073,334 @@ impl ::protobuf::Message for GridRow { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "id", - |m: &GridRow| { &m.id }, - |m: &mut GridRow| { &mut m.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: &GridRow| { &m.grid_id }, - |m: &mut GridRow| { &mut m.grid_id }, + |m: &RawRow| { &m.grid_id }, + |m: &mut RawRow| { &mut m.grid_id }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( - "modified_time", - |m: &GridRow| { &m.modified_time }, - |m: &mut GridRow| { &mut m.modified_time }, - )); - fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( + fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( "cell_by_field_id", - |m: &GridRow| { &m.cell_by_field_id }, - |m: &mut GridRow| { &mut m.cell_by_field_id }, + |m: &RawRow| { &m.cell_by_field_id }, + |m: &mut RawRow| { &mut m.cell_by_field_id }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GridRow", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RawRow", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static GridRow { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GridRow::new) + fn default_instance() -> &'static RawRow { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RawRow::new) } } -impl ::protobuf::Clear for GridRow { +impl ::protobuf::Clear for RawRow { fn clear(&mut self) { self.id.clear(); self.grid_id.clear(); - self.modified_time = 0; self.cell_by_field_id.clear(); self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for GridRow { +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 GridRow { +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: ::std::string::String, + // 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()) + } + + // 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 RawCell { + 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() -> 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_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "data", + |m: &RawCell| { &m.data }, + |m: &mut RawCell| { &mut m.data }, + )); + ::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.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) } @@ -2568,7 +2409,7 @@ impl ::protobuf::reflect::ProtobufValue for GridRow { #[derive(PartialEq,Clone,Default)] pub struct RepeatedRow { // message fields - pub items: ::protobuf::RepeatedField, + pub items: ::protobuf::RepeatedField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -2585,10 +2426,10 @@ impl RepeatedRow { ::std::default::Default::default() } - // repeated .GridRow items = 1; + // repeated .Row items = 1; - pub fn get_items(&self) -> &[GridRow] { + pub fn get_items(&self) -> &[Row] { &self.items } pub fn clear_items(&mut self) { @@ -2596,17 +2437,17 @@ 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()) } } @@ -2693,7 +2534,7 @@ impl ::protobuf::Message for RepeatedRow { 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 }, @@ -2732,25 +2573,23 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedRow { } #[derive(PartialEq,Clone,Default)] -pub struct GridCell { +pub struct Row { // message fields pub id: ::std::string::String, - pub row_id: ::std::string::String, - pub field_id: ::std::string::String, - pub content: ::std::string::String, + pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, Cell>, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a GridCell { - fn default() -> &'a GridCell { - ::default_instance() +impl<'a> ::std::default::Default for &'a Row { + fn default() -> &'a Row { + ::default_instance() } } -impl GridCell { - pub fn new() -> GridCell { +impl Row { + pub fn new() -> Row { ::std::default::Default::default() } @@ -2780,33 +2619,204 @@ impl GridCell { ::std::mem::replace(&mut self.id, ::std::string::String::new()) } - // string row_id = 2; + // repeated .Row.CellByFieldIdEntry cell_by_field_id = 2; - pub fn get_row_id(&self) -> &str { - &self.row_id + pub fn get_cell_by_field_id(&self) -> &::std::collections::HashMap<::std::string::String, Cell> { + &self.cell_by_field_id } - pub fn clear_row_id(&mut self) { - self.row_id.clear(); + pub fn clear_cell_by_field_id(&mut self) { + self.cell_by_field_id.clear(); } // Param is passed by value, moved - pub fn set_row_id(&mut self, v: ::std::string::String) { - self.row_id = v; + pub fn set_cell_by_field_id(&mut self, v: ::std::collections::HashMap<::std::string::String, Cell>) { + 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, Cell> { + &mut self.cell_by_field_id + } + + // Take field + 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()) + } +} + +impl ::protobuf::Message for Row { + 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_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.id.is_empty() { + 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); + 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)?; + } + ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(2, &self.cell_by_field_id, 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() -> Row { + Row::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: &Row| { &m.id }, + |m: &mut Row| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( + "cell_by_field_id", + |m: &Row| { &m.cell_by_field_id }, + |m: &mut Row| { &mut m.cell_by_field_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Row", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Row { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Row::new) + } +} + +impl ::protobuf::Clear for Row { + fn clear(&mut self) { + self.id.clear(); + self.cell_by_field_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Row { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Row { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[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 + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Cell { + fn default() -> &'a Cell { + ::default_instance() + } +} + +impl Cell { + pub fn new() -> 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_row_id(&mut self) -> &mut ::std::string::String { - &mut self.row_id + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id } // Take field - pub fn take_row_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) } - // string field_id = 3; + // string field_id = 2; pub fn get_field_id(&self) -> &str { @@ -2832,7 +2842,7 @@ impl GridCell { ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) } - // string content = 4; + // string content = 3; pub fn get_content(&self) -> &str { @@ -2859,7 +2869,7 @@ impl GridCell { } } -impl ::protobuf::Message for GridCell { +impl ::protobuf::Message for Cell { fn is_initialized(&self) -> bool { true } @@ -2872,12 +2882,9 @@ impl ::protobuf::Message for GridCell { ::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 => { + 3 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.content)?; }, _ => { @@ -2895,14 +2902,11 @@ impl ::protobuf::Message for GridCell { 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(2, &self.field_id); } if !self.content.is_empty() { - my_size += ::protobuf::rt::string_size(4, &self.content); + my_size += ::protobuf::rt::string_size(3, &self.content); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -2913,14 +2917,11 @@ impl ::protobuf::Message for GridCell { 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(2, &self.field_id)?; } if !self.content.is_empty() { - os.write_string(4, &self.content)?; + os.write_string(3, &self.content)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -2952,8 +2953,8 @@ impl ::protobuf::Message for GridCell { Self::descriptor_static() } - fn new() -> GridCell { - GridCell::new() + fn new() -> Cell { + Cell::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -2962,55 +2963,49 @@ impl ::protobuf::Message for GridCell { let mut fields = ::std::vec::Vec::new(); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "id", - |m: &GridCell| { &m.id }, - |m: &mut GridCell| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "row_id", - |m: &GridCell| { &m.row_id }, - |m: &mut GridCell| { &mut m.row_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: &GridCell| { &m.field_id }, - |m: &mut GridCell| { &mut m.field_id }, + |m: &Cell| { &m.field_id }, + |m: &mut Cell| { &mut m.field_id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "content", - |m: &GridCell| { &m.content }, - |m: &mut GridCell| { &mut m.content }, + |m: &Cell| { &m.content }, + |m: &mut Cell| { &mut m.content }, )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "GridCell", + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Cell", fields, file_descriptor_proto() ) }) } - fn default_instance() -> &'static GridCell { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(GridCell::new) + fn default_instance() -> &'static Cell { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Cell::new) } } -impl ::protobuf::Clear for GridCell { +impl ::protobuf::Clear for Cell { fn clear(&mut self) { self.id.clear(); - self.row_id.clear(); self.field_id.clear(); self.content.clear(); self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for GridCell { +impl ::std::fmt::Debug for Cell { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for GridCell { +impl ::protobuf::reflect::ProtobufValue for Cell { fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { ::protobuf::reflect::ReflectValueRef::Message(self) } @@ -3334,6 +3329,415 @@ impl ::protobuf::reflect::ProtobufValue for GridId { } } +#[derive(PartialEq,Clone,Default)] +pub struct Filter { + // message fields + pub id: ::std::string::String, + pub name: ::std::string::String, + pub desc: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Filter { + fn default() -> &'a Filter { + ::default_instance() + } +} + +impl Filter { + pub fn new() -> Filter { + ::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()) + } +} + +impl ::protobuf::Message for Filter { + 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)?; + }, + _ => { + ::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); + } + 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)?; + } + 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() -> Filter { + Filter::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: &Filter| { &m.id }, + |m: &mut Filter| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &Filter| { &m.name }, + |m: &mut Filter| { &mut m.name }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "desc", + |m: &Filter| { &m.desc }, + |m: &mut Filter| { &mut m.desc }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "Filter", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static Filter { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(Filter::new) + } +} + +impl ::protobuf::Clear for Filter { + fn clear(&mut self) { + self.id.clear(); + self.name.clear(); + self.desc.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Filter { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Filter { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct RepeatedFilter { + // 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 RepeatedFilter { + fn default() -> &'a RepeatedFilter { + ::default_instance() + } +} + +impl RepeatedFilter { + pub fn new() -> RepeatedFilter { + ::std::default::Default::default() + } + + // repeated .Filter items = 1; + + + pub fn get_items(&self) -> &[Filter] { + &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 RepeatedFilter { + 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() -> RepeatedFilter { + RepeatedFilter::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: &RepeatedFilter| { &m.items }, + |m: &mut RepeatedFilter| { &mut m.items }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "RepeatedFilter", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static RepeatedFilter { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(RepeatedFilter::new) + } +} + +impl ::protobuf::Clear for RepeatedFilter { + fn clear(&mut self) { + self.items.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for RepeatedFilter { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for RepeatedFilter { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum FieldType { RichText = 0, @@ -3397,44 +3801,49 @@ impl ::protobuf::reflect::ProtobufValue for FieldType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ngrid.proto\"\xb8\x01\n\x04Grid\x12\x17\n\x07grid_id\x18\x01\x20\x01(\ - \tR\x06gridId\x12-\n\x07filters\x18\x02\x20\x01(\x0b2\x13.RepeatedGridFi\ - lterR\x07filters\x126\n\x0cfield_orders\x18\x03\x20\x01(\x0b2\x13.Repeat\ - edFieldOrderR\x0bfieldOrders\x120\n\nrow_orders\x18\x04\x20\x01(\x0b2\ - \x11.RepeatedRowOrderR\trowOrders\"D\n\nGridFilter\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\"7\n\x12RepeatedGridFilter\ - \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.GridFilterR\x05items\"G\n\nFi\ - eldOrder\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x1e\n\ - \nvisibility\x18\x02\x20\x01(\x08R\nvisibility\"7\n\x12RepeatedFieldOrde\ - r\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\x04n\ - ame\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\tfieldTyp\ - e\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06frozen\x12\x14\n\x05width\ - \x18\x06\x20\x01(\x05R\x05width\x12+\n\x0ctype_options\x18\x07\x20\x01(\ - \x0b2\x08.AnyDataR\x0btypeOptions\"-\n\rRepeatedField\x12\x1c\n\x05items\ - \x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"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\"Z\n\x08RowOrder\x12\x17\n\x07grid_id\x18\x01\x20\x01(\t\ - R\x06gridId\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x1e\n\n\ - visibility\x18\x03\x20\x01(\x08R\nvisibility\"3\n\x10RepeatedRowOrder\ - \x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\t.RowOrderR\x05items\"\xea\x01\ - \n\x07GridRow\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x17\n\x07gri\ - d_id\x18\x02\x20\x01(\tR\x06gridId\x12#\n\rmodified_time\x18\x03\x20\x01\ - (\x03R\x0cmodifiedTime\x12D\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2\ - \x1b.GridRow.CellByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdE\ - ntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\ - \x02\x20\x01(\x0b2\t.GridCellR\x05value:\x028\x01\"-\n\x0bRepeatedRow\ - \x12\x1e\n\x05items\x18\x01\x20\x03(\x0b2\x08.GridRowR\x05items\"f\n\x08\ - GridCell\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\x18\n\x07content\x18\x04\x20\x01(\tR\x07content\"'\n\x11\ - CreateGridPayload\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\tFieldTyp\ - e\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08Dat\ - eTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\ - \x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\ + \n\ngrid.proto\"\xab\x01\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ + \x02id\x12)\n\x07filters\x18\x02\x20\x01(\x0b2\x0f.RepeatedFilterR\x07fi\ + lters\x126\n\x0cfield_orders\x18\x03\x20\x01(\x0b2\x13.RepeatedFieldOrde\ + rR\x0bfieldOrders\x120\n\nrow_orders\x18\x04\x20\x01(\x0b2\x11.RepeatedR\ + owOrderR\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\"\xc2\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\"_\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\x12\n\x04data\x18\x04\x20\x01(\ + \tR\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(\t\ + R\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByF\ + ieldIdEntryR\rcellByFieldId\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03ke\ + y\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\"'\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\"@\n\x06Filter\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\"/\n\x0eRepeatedF\ + ilter\x12\x1d\n\x05items\x18\x01\x20\x03(\x0b2\x07.FilterR\x05items*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 352a54c5c8..16b14f76c9 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,19 +1,11 @@ syntax = "proto3"; message Grid { - string grid_id = 1; - RepeatedGridFilter filters = 2; + string id = 1; + RepeatedFilter filters = 2; RepeatedFieldOrder field_orders = 3; RepeatedRowOrder row_orders = 4; } -message GridFilter { - string id = 1; - string name = 2; - string desc = 3; -} -message RepeatedGridFilter { - repeated GridFilter items = 1; -} message FieldOrder { string field_id = 1; bool visibility = 2; @@ -45,20 +37,28 @@ message RowOrder { message RepeatedRowOrder { repeated RowOrder items = 1; } -message GridRow { +message RawRow { string id = 1; string grid_id = 2; - int64 modified_time = 3; - map cell_by_field_id = 4; + map cell_by_field_id = 3; } -message RepeatedRow { - repeated GridRow items = 1; -} -message GridCell { +message RawCell { string id = 1; string row_id = 2; string field_id = 3; - string content = 4; + string data = 4; +} +message RepeatedRow { + repeated Row items = 1; +} +message Row { + string id = 1; + map cell_by_field_id = 2; +} +message Cell { + string id = 1; + string field_id = 2; + string content = 3; } message CreateGridPayload { string name = 1; @@ -66,6 +66,14 @@ message CreateGridPayload { message GridId { string value = 1; } +message Filter { + string id = 1; + string name = 2; + string desc = 3; +} +message RepeatedFilter { + repeated Filter items = 1; +} enum FieldType { RichText = 0; Number = 1; From 49807a0b57d0e9feb124cc6c36599374c7d3fb6b Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 4 Mar 2022 18:11:12 +0800 Subject: [PATCH 08/17] feat: config grid db --- .../flowy-grid-data-model/grid.pb.dart | 245 +++--- .../flowy-grid-data-model/grid.pbjson.dart | 42 +- frontend/rust-lib/Cargo.lock | 12 + .../rust-lib/flowy-block/src/web_socket.rs | 2 +- .../src/services/view/controller.rs | 4 +- .../flowy-folder/src/services/web_socket.rs | 2 +- frontend/rust-lib/flowy-grid/Cargo.toml | 17 +- frontend/rust-lib/flowy-grid/Flowy.toml | 2 +- frontend/rust-lib/flowy-grid/src/lib.rs | 2 +- .../{cell_service => services}/cell_data.rs | 2 +- .../flowy-grid/src/services/grid_editor.rs | 143 ++++ .../src/{cell_service => services}/mod.rs | 3 + .../flowy-grid/src/services/row_kv.rs | 95 +++ .../{cell_service => services}/stringify.rs | 4 +- .../src/{cell_service => services}/util.rs | 2 +- .../flowy-net/src/local_server/server.rs | 10 +- .../rust-lib/flowy-sync/src/ws_manager.rs | 10 +- frontend/rust-lib/flowy-test/src/helper.rs | 4 +- frontend/rust-lib/flowy-test/src/lib.rs | 4 +- .../tests/event/user_profile_test.rs | 4 +- shared-lib/Cargo.lock | 4 + shared-lib/flowy-collaboration/Cargo.toml | 1 + .../src/client_folder/builder.rs | 11 +- .../src/client_folder/folder_pad.rs | 102 +-- .../src/client_grid/grid_pad.rs | 141 ++++ .../src/client_grid/mod.rs | 3 + shared-lib/flowy-collaboration/src/lib.rs | 1 + shared-lib/flowy-collaboration/src/util.rs | 27 + shared-lib/flowy-grid-data-model/Cargo.toml | 3 + .../src/entities/grid.rs | 86 +- .../src/protobuf/model/grid.rs | 788 +++++++----------- .../src/protobuf/proto/grid.proto | 19 +- .../flowy-grid-data-model/tests/serde_test.rs | 58 ++ shared-lib/lib-infra/src/lib.rs | 2 +- 34 files changed, 1070 insertions(+), 785 deletions(-) rename frontend/rust-lib/flowy-grid/src/{cell_service => services}/cell_data.rs (99%) create mode 100644 frontend/rust-lib/flowy-grid/src/services/grid_editor.rs rename frontend/rust-lib/flowy-grid/src/{cell_service => services}/mod.rs (66%) create mode 100644 frontend/rust-lib/flowy-grid/src/services/row_kv.rs rename frontend/rust-lib/flowy-grid/src/{cell_service => services}/stringify.rs (95%) rename frontend/rust-lib/flowy-grid/src/{cell_service => services}/util.rs (98%) create mode 100644 shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs create mode 100644 shared-lib/flowy-collaboration/src/client_grid/mod.rs create mode 100644 shared-lib/flowy-grid-data-model/tests/serde_test.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 ba0b827df8..54139582fe 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 @@ -16,16 +16,14 @@ 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') ? '' : 'filters', subBuilder: RepeatedFilter.create) - ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', subBuilder: RepeatedFieldOrder.create) - ..aOM(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', subBuilder: RepeatedRowOrder.create) + ..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) ..hasRequiredFields = false ; Grid._() : super(); factory Grid({ $core.String? id, - RepeatedFilter? filters, RepeatedFieldOrder? fieldOrders, RepeatedRowOrder? rowOrders, }) { @@ -33,9 +31,6 @@ class Grid extends $pb.GeneratedMessage { if (id != null) { _result.id = id; } - if (filters != null) { - _result.filters = filters; - } if (fieldOrders != null) { _result.fieldOrders = fieldOrders; } @@ -75,37 +70,26 @@ class Grid extends $pb.GeneratedMessage { void clearId() => clearField(1); @$pb.TagNumber(2) - RepeatedFilter get filters => $_getN(1); + RepeatedFieldOrder get fieldOrders => $_getN(1); @$pb.TagNumber(2) - set filters(RepeatedFilter v) { setField(2, v); } + set fieldOrders(RepeatedFieldOrder v) { setField(2, v); } @$pb.TagNumber(2) - $core.bool hasFilters() => $_has(1); + $core.bool hasFieldOrders() => $_has(1); @$pb.TagNumber(2) - void clearFilters() => clearField(2); + void clearFieldOrders() => clearField(2); @$pb.TagNumber(2) - RepeatedFilter ensureFilters() => $_ensure(1); + RepeatedFieldOrder ensureFieldOrders() => $_ensure(1); @$pb.TagNumber(3) - RepeatedFieldOrder get fieldOrders => $_getN(2); + RepeatedRowOrder get rowOrders => $_getN(2); @$pb.TagNumber(3) - set fieldOrders(RepeatedFieldOrder v) { setField(3, v); } + set rowOrders(RepeatedRowOrder v) { setField(3, v); } @$pb.TagNumber(3) - $core.bool hasFieldOrders() => $_has(2); + $core.bool hasRowOrders() => $_has(2); @$pb.TagNumber(3) - void clearFieldOrders() => clearField(3); + void clearRowOrders() => clearField(3); @$pb.TagNumber(3) - RepeatedFieldOrder ensureFieldOrders() => $_ensure(2); - - @$pb.TagNumber(4) - RepeatedRowOrder get rowOrders => $_getN(3); - @$pb.TagNumber(4) - set rowOrders(RepeatedRowOrder v) { setField(4, v); } - @$pb.TagNumber(4) - $core.bool hasRowOrders() => $_has(3); - @$pb.TagNumber(4) - void clearRowOrders() => clearField(4); - @$pb.TagNumber(4) - RepeatedRowOrder ensureRowOrders() => $_ensure(3); + RepeatedRowOrder ensureRowOrders() => $_ensure(2); } class FieldOrder extends $pb.GeneratedMessage { @@ -890,6 +874,95 @@ 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') @@ -984,119 +1057,3 @@ class GridId extends $pb.GeneratedMessage { void clearValue() => clearField(1); } -class Filter extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Filter', 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') - ..hasRequiredFields = false - ; - - Filter._() : super(); - factory Filter({ - $core.String? id, - $core.String? name, - $core.String? desc, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (name != null) { - _result.name = name; - } - if (desc != null) { - _result.desc = desc; - } - return _result; - } - factory Filter.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Filter.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') - Filter clone() => Filter()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Filter copyWith(void Function(Filter) updates) => super.copyWith((message) => updates(message as Filter)) as Filter; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Filter create() => Filter._(); - Filter createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static Filter getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static Filter? _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); -} - -class RepeatedFilter extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedFilter', createEmptyInstance: create) - ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Filter.create) - ..hasRequiredFields = false - ; - - RepeatedFilter._() : super(); - factory RepeatedFilter({ - $core.Iterable? items, - }) { - final _result = create(); - if (items != null) { - _result.items.addAll(items); - } - return _result; - } - factory RepeatedFilter.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RepeatedFilter.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') - RepeatedFilter clone() => RepeatedFilter()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RepeatedFilter copyWith(void Function(RepeatedFilter) updates) => super.copyWith((message) => updates(message as RepeatedFilter)) as RepeatedFilter; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RepeatedFilter create() => RepeatedFilter._(); - RepeatedFilter createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static RepeatedFilter getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static RepeatedFilter? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get items => $_getList(0); -} - 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 205acfd611..23f606194a 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 @@ -28,14 +28,13 @@ const Grid$json = const { '1': 'Grid', '2': const [ const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, - const {'1': 'filters', '3': 2, '4': 1, '5': 11, '6': '.RepeatedFilter', '10': 'filters'}, - const {'1': 'field_orders', '3': 3, '4': 1, '5': 11, '6': '.RepeatedFieldOrder', '10': 'fieldOrders'}, - const {'1': 'row_orders', '3': 4, '4': 1, '5': 11, '6': '.RepeatedRowOrder', '10': 'rowOrders'}, + 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'}, ], }; /// Descriptor for `Grid`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIpCgdmaWx0ZXJzGAIgASgLMg8uUmVwZWF0ZWRGaWx0ZXJSB2ZpbHRlcnMSNgoMZmllbGRfb3JkZXJzGAMgASgLMhMuUmVwZWF0ZWRGaWVsZE9yZGVyUgtmaWVsZE9yZGVycxIwCgpyb3dfb3JkZXJzGAQgASgLMhEuUmVwZWF0ZWRSb3dPcmRlclIJcm93T3JkZXJz'); +final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBI2CgxmaWVsZF9vcmRlcnMYAiABKAsyEy5SZXBlYXRlZEZpZWxkT3JkZXJSC2ZpZWxkT3JkZXJzEjAKCnJvd19vcmRlcnMYAyABKAsyES5SZXBlYXRlZFJvd09yZGVyUglyb3dPcmRlcnM='); @$core.Deprecated('Use fieldOrderDescriptor instead') const FieldOrder$json = const { '1': 'FieldOrder', @@ -196,6 +195,19 @@ 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', @@ -216,25 +228,3 @@ const GridId$json = const { /// Descriptor for `GridId`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridIdDescriptor = $convert.base64Decode('CgZHcmlkSWQSFAoFdmFsdWUYASABKAlSBXZhbHVl'); -@$core.Deprecated('Use filterDescriptor instead') -const Filter$json = const { - '1': 'Filter', - '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'}, - ], -}; - -/// Descriptor for `Filter`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List filterDescriptor = $convert.base64Decode('CgZGaWx0ZXISDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYw=='); -@$core.Deprecated('Use repeatedFilterDescriptor instead') -const RepeatedFilter$json = const { - '1': 'RepeatedFilter', - '2': const [ - const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Filter', '10': 'items'}, - ], -}; - -/// Descriptor for `RepeatedFilter`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List repeatedFilterDescriptor = $convert.base64Decode('Cg5SZXBlYXRlZEZpbHRlchIdCgVpdGVtcxgBIAMoCzIHLkZpbHRlclIFaXRlbXM='); diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 05d59f7879..c4aa021bdc 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -909,6 +909,7 @@ dependencies = [ "dissimilar", "flowy-derive", "flowy-folder-data-model", + "flowy-grid-data-model", "futures", "lib-infra", "lib-ot", @@ -1048,14 +1049,22 @@ dependencies = [ name = "flowy-grid" version = "0.1.0" dependencies = [ + "async-trait", "bytes", "chrono", + "dart-notify", + "diesel", + "flowy-collaboration", "flowy-derive", "flowy-error", "flowy-grid-data-model", + "flowy-sync", "lazy_static", "lib-dispatch", "lib-infra", + "lib-ot", + "lib-sqlite", + "parking_lot", "protobuf", "rust_decimal", "rusty-money", @@ -1073,8 +1082,11 @@ dependencies = [ "flowy-derive", "lib-infra", "protobuf", + "serde", + "serde_json", "strum", "strum_macros", + "uuid", ] [[package]] diff --git a/frontend/rust-lib/flowy-block/src/web_socket.rs b/frontend/rust-lib/flowy-block/src/web_socket.rs index ee8db49cf4..27ec604129 100644 --- a/frontend/rust-lib/flowy-block/src/web_socket.rs +++ b/frontend/rust-lib/flowy-block/src/web_socket.rs @@ -97,7 +97,7 @@ impl RevisionWSDataStream for BlockRevisionWSDataStream { } pub(crate) struct BlockWSDataSink(pub(crate) Arc); -impl RevisionWSDataIterator for BlockWSDataSink { +impl RevisionWebSocketSink for BlockWSDataSink { fn next(&self) -> FutureResult, FlowyError> { let sink_provider = self.0.clone(); FutureResult::new(async move { sink_provider.next().await }) 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 72e29c1b60..32e4aa5136 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -25,7 +25,7 @@ use flowy_block::BlockManager; use flowy_database::kv::KV; use flowy_folder_data_model::entities::share::{ExportData, ExportParams}; -use lib_infra::uuid_string; +use lib_infra::uuid; const LATEST_VIEW_ID: &str = "latest_view_id"; @@ -176,7 +176,7 @@ impl ViewController { thumbnail: view.thumbnail, data_type: view.data_type, data: document_json, - view_id: uuid_string(), + view_id: uuid(), ext_data: view.ext_data, plugin_type: view.plugin_type, }; diff --git a/frontend/rust-lib/flowy-folder/src/services/web_socket.rs b/frontend/rust-lib/flowy-folder/src/services/web_socket.rs index 438b3f52d3..98902b8878 100644 --- a/frontend/rust-lib/flowy-folder/src/services/web_socket.rs +++ b/frontend/rust-lib/flowy-folder/src/services/web_socket.rs @@ -43,7 +43,7 @@ pub(crate) async fn make_folder_ws_manager( } pub(crate) struct FolderWSDataSink(Arc); -impl RevisionWSDataIterator for FolderWSDataSink { +impl RevisionWebSocketSink for FolderWSDataSink { fn next(&self) -> FutureResult, FlowyError> { let sink_provider = self.0.clone(); FutureResult::new(async move { sink_provider.next().await }) diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index 31030c5d28..6258f9cc80 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -6,13 +6,19 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -flowy-grid-data-model = { path = "../../../shared-lib/flowy-grid-data-model" } lib-dispatch = { path = "../lib-dispatch" } -lib-infra = { path = "../../../shared-lib/lib-infra" } +dart-notify = { path = "../dart-notify" } +lib-sqlite = { path = "../lib-sqlite" } +flowy-sync = { path = "../flowy-sync" } flowy-error = { path = "../flowy-error"} +flowy-derive = { path = "../../../shared-lib/flowy-derive" } +lib-ot = { path = "../../../shared-lib/lib-ot" } +lib-infra = { path = "../../../shared-lib/lib-infra" } +flowy-grid-data-model = { path = "../../../shared-lib/flowy-grid-data-model" } +flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration" } + strum = "0.21" strum_macros = "0.21" -flowy-derive = { path = "../../../shared-lib/flowy-derive" } tracing = { version = "0.1", features = ["log"] } protobuf = {version = "2.18.0"} rust_decimal = "1.8.1" @@ -21,6 +27,11 @@ lazy_static = "1.4.0" chrono = "0.4.19" uuid = { version = "0.8", features = ["serde", "v4"] } bytes = { version = "1.0" } +async-trait = "0.1.52" +diesel = {version = "1.4.8", features = ["sqlite"]} + + +parking_lot = "0.11" [build-dependencies] lib-infra = { path = "../../../shared-lib/lib-infra", features = ["protobuf_file_gen", "proto_gen"] } diff --git a/frontend/rust-lib/flowy-grid/Flowy.toml b/frontend/rust-lib/flowy-grid/Flowy.toml index 1f99bcf43d..d7c3d8260d 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/cell_service/cell_data.rs"] +proto_crates = ["src/event_map.rs", "src/services/cell_data.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 b7a4baf831..2645d2b121 100644 --- a/frontend/rust-lib/flowy-grid/src/lib.rs +++ b/frontend/rust-lib/flowy-grid/src/lib.rs @@ -5,5 +5,5 @@ mod controller; mod event_handler; mod event_map; -mod cell_service; mod protobuf; +mod services; diff --git a/frontend/rust-lib/flowy-grid/src/cell_service/cell_data.rs b/frontend/rust-lib/flowy-grid/src/services/cell_data.rs similarity index 99% rename from frontend/rust-lib/flowy-grid/src/cell_service/cell_data.rs rename to frontend/rust-lib/flowy-grid/src/services/cell_data.rs index fdd62b796c..c44c320468 100644 --- a/frontend/rust-lib/flowy-grid/src/cell_service/cell_data.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell_data.rs @@ -1,5 +1,5 @@ -use crate::cell_service::util::*; use crate::impl_any_data; +use crate::services::util::*; use bytes::Bytes; use chrono::format::strftime::StrftimeItems; use chrono::NaiveDateTime; diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs new file mode 100644 index 0000000000..a97230f851 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -0,0 +1,143 @@ +use crate::services::row_kv::{RowKVPersistence, RowKVTransaction}; +use flowy_collaboration::client_grid::{GridChange, GridPad}; +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::{GridId, RawRow}; +use flowy_sync::{ + RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder, RevisionPersistence, + RevisionWebSocket, RevisionWebSocketManager, +}; +use lib_infra::future::FutureResult; +use lib_ot::core::PlainTextAttributes; +use lib_sqlite::ConnectionPool; +use parking_lot::RwLock; +use std::sync::Arc; + +pub struct ClientGridEditor { + user_id: String, + grid_id: GridId, + grid: Arc>, + rev_manager: Arc, + kv: Arc, +} + +impl ClientGridEditor { + pub async fn new( + user_id: &str, + grid_id: &GridId, + token: &str, + pool: Arc, + _web_socket: Arc, + ) -> FlowyResult { + let rev_persistence = Arc::new(RevisionPersistence::new(user_id, grid_id.as_ref(), pool.clone())); + let mut rev_manager = RevisionManager::new(user_id, grid_id.as_ref(), rev_persistence); + let cloud = Arc::new(GridRevisionCloudService { + token: token.to_string(), + }); + let grid = Arc::new(RwLock::new( + rev_manager.load::(cloud).await?, + )); + let rev_manager = Arc::new(rev_manager); + let kv = Arc::new(RowKVPersistence::new(pool)); + + let user_id = user_id.to_owned(); + let grid_id = grid_id.to_owned(); + Ok(Self { + user_id, + grid_id, + grid, + rev_manager, + kv, + }) + } + + pub async fn create_row(&self, row: RawRow) -> FlowyResult<()> { + let _ = self + .modify(|grid| { + let change = grid.create_row(&row)?; + Ok(change) + }) + .await?; + + let _ = self.kv.set(row)?; + Ok(()) + } + + pub async fn modify(&self, f: F) -> FlowyResult<()> + where + F: FnOnce(&mut GridPad) -> FlowyResult>, + { + let mut write_guard = self.grid.write(); + match f(&mut *write_guard)? { + None => {} + Some(change) => { + let _ = self.apply_change(change).await?; + } + } + Ok(()) + } + + async fn apply_change(&self, change: GridChange) -> FlowyResult<()> { + let GridChange { delta, md5 } = change; + 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, + &self.user_id, + md5, + ); + let _ = self + .rev_manager + .add_local_revision::(&revision) + .await?; + Ok(()) + } +} + +struct GridPadBuilder(); +impl RevisionObjectBuilder for GridPadBuilder { + type Output = GridPad; + + fn build_object(_object_id: &str, revisions: Vec) -> FlowyResult { + let pad = GridPad::from_revisions(revisions)?; + Ok(pad) + } +} + +struct GridRevisionCloudService { + #[allow(dead_code)] + token: String, +} + +impl RevisionCloudService for GridRevisionCloudService { + #[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 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(); + 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)) + } +} diff --git a/frontend/rust-lib/flowy-grid/src/cell_service/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs similarity index 66% rename from frontend/rust-lib/flowy-grid/src/cell_service/mod.rs rename to frontend/rust-lib/flowy-grid/src/services/mod.rs index b781258695..48cb2faf89 100644 --- a/frontend/rust-lib/flowy-grid/src/cell_service/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -2,4 +2,7 @@ mod stringify; mod util; pub mod cell_data; +pub mod grid_editor; +mod row_kv; + pub use stringify::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/row_kv.rs b/frontend/rust-lib/flowy-grid/src/services/row_kv.rs new file mode 100644 index 0000000000..11f380fe16 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/row_kv.rs @@ -0,0 +1,95 @@ +use async_trait::async_trait; +use diesel::SqliteConnection; +use flowy_error::{FlowyError, FlowyResult}; +use flowy_grid_data_model::entities::RawRow; +use lib_infra::future::{BoxResultFuture, FutureResult}; +use lib_sqlite::{ConnectionManager, ConnectionPool}; +use std::sync::Arc; + +pub trait RowKVTransaction { + fn get(&self, row_id: &str) -> FlowyResult>; + fn set(&self, row: RawRow) -> FlowyResult<()>; + fn remove(&self, row_id: &str) -> FlowyResult<()>; + + fn batch_get(&self, ids: Vec) -> FlowyResult<()>; + fn batch_set(&self, rows: Vec) -> FlowyResult<()>; + fn batch_delete(&self, ids: Vec) -> FlowyResult<()>; +} + +pub struct RowKVPersistence { + pool: Arc, +} + +impl RowKVPersistence { + pub fn new(pool: Arc) -> Self { + Self { pool } + } + + pub fn begin_transaction(&self, f: F) -> FlowyResult + where + F: for<'a> FnOnce(Box) -> FlowyResult, + { + let conn = self.pool.get()?; + conn.immediate_transaction::<_, FlowyError, _>(|| { + let sql_transaction = SqliteTransaction { conn: &conn }; + f(Box::new(sql_transaction)) + }) + } +} + +impl RowKVTransaction for RowKVPersistence { + fn get(&self, row_id: &str) -> FlowyResult> { + self.begin_transaction(|transaction| transaction.get(row_id)) + } + + fn set(&self, row: RawRow) -> FlowyResult<()> { + self.begin_transaction(|transaction| transaction.set(row)) + } + + fn remove(&self, row_id: &str) -> FlowyResult<()> { + self.begin_transaction(|transaction| transaction.remove(row_id)) + } + + fn batch_get(&self, ids: Vec) -> FlowyResult<()> { + self.begin_transaction(|transaction| transaction.batch_get(ids)) + } + + fn batch_set(&self, rows: Vec) -> FlowyResult<()> { + self.begin_transaction(|transaction| transaction.batch_set(rows)) + } + + fn batch_delete(&self, ids: Vec) -> FlowyResult<()> { + self.begin_transaction(|transaction| transaction.batch_delete(ids)) + } +} + +pub struct SqliteTransaction<'a> { + conn: &'a SqliteConnection, +} + +#[async_trait] +impl<'a> RowKVTransaction for SqliteTransaction<'a> { + fn get(&self, row_id: &str) -> FlowyResult> { + todo!() + } + + fn set(&self, row: RawRow) -> FlowyResult<()> { + todo!() + } + + fn remove(&self, row_id: &str) -> FlowyResult<()> { + todo!() + } + + fn batch_get(&self, ids: Vec) -> FlowyResult<()> { + todo!() + } + + fn batch_set(&self, rows: Vec) -> FlowyResult<()> { + todo!() + } + + fn batch_delete(&self, ids: Vec) -> FlowyResult<()> { + todo!() + } +} diff --git a/frontend/rust-lib/flowy-grid/src/cell_service/stringify.rs b/frontend/rust-lib/flowy-grid/src/services/stringify.rs similarity index 95% rename from frontend/rust-lib/flowy-grid/src/cell_service/stringify.rs rename to frontend/rust-lib/flowy-grid/src/services/stringify.rs index 0163a38368..299b7e8c96 100644 --- a/frontend/rust-lib/flowy-grid/src/cell_service/stringify.rs +++ b/frontend/rust-lib/flowy-grid/src/services/stringify.rs @@ -1,5 +1,5 @@ -use crate::cell_service::cell_data::*; -use crate::cell_service::util::*; +use crate::services::cell_data::*; +use crate::services::util::*; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; diff --git a/frontend/rust-lib/flowy-grid/src/cell_service/util.rs b/frontend/rust-lib/flowy-grid/src/services/util.rs similarity index 98% rename from frontend/rust-lib/flowy-grid/src/cell_service/util.rs rename to frontend/rust-lib/flowy-grid/src/services/util.rs index 7081b6d4f0..5ed96fc811 100644 --- a/frontend/rust-lib/flowy-grid/src/cell_service/util.rs +++ b/frontend/rust-lib/flowy-grid/src/services/util.rs @@ -1,4 +1,4 @@ -use crate::cell_service::cell_data::FlowyMoney; +use crate::services::cell_data::FlowyMoney; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; use lazy_static::lazy_static; 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 09724d2de5..24fda76639 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/server.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/server.rs @@ -259,7 +259,7 @@ use flowy_user::event_map::UserCloudService; use flowy_user_data_model::entities::{ SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile, }; -use lib_infra::{future::FutureResult, timestamp, uuid_string}; +use lib_infra::{future::FutureResult, timestamp, uuid}; impl FolderCouldServiceV1 for LocalServer { fn init(&self) {} @@ -267,7 +267,7 @@ impl FolderCouldServiceV1 for LocalServer { fn create_workspace(&self, _token: &str, params: CreateWorkspaceParams) -> FutureResult { let time = timestamp(); let workspace = Workspace { - id: uuid_string(), + id: uuid(), name: params.name, desc: params.desc, apps: RepeatedApp::default(), @@ -327,7 +327,7 @@ impl FolderCouldServiceV1 for LocalServer { fn create_app(&self, _token: &str, params: CreateAppParams) -> FutureResult { let time = timestamp(); let app = App { - id: uuid_string(), + id: uuid(), workspace_id: params.workspace_id, name: params.name, desc: params.desc, @@ -369,7 +369,7 @@ impl FolderCouldServiceV1 for LocalServer { impl UserCloudService for LocalServer { fn sign_up(&self, params: SignUpParams) -> FutureResult { - let uid = uuid_string(); + let uid = uuid(); FutureResult::new(async move { Ok(SignUpResponse { user_id: uid.clone(), @@ -381,7 +381,7 @@ impl UserCloudService for LocalServer { } fn sign_in(&self, params: SignInParams) -> FutureResult { - let user_id = uuid_string(); + let user_id = uuid(); FutureResult::new(async { Ok(SignInResponse { user_id: user_id.clone(), diff --git a/frontend/rust-lib/flowy-sync/src/ws_manager.rs b/frontend/rust-lib/flowy-sync/src/ws_manager.rs index a151a58038..1a5891dbbb 100644 --- a/frontend/rust-lib/flowy-sync/src/ws_manager.rs +++ b/frontend/rust-lib/flowy-sync/src/ws_manager.rs @@ -30,7 +30,7 @@ pub trait RevisionWSDataStream: Send + Sync { // The sink provides the data that will be sent through the web socket to the // backend. -pub trait RevisionWSDataIterator: Send + Sync { +pub trait RevisionWebSocketSink: Send + Sync { fn next(&self) -> FutureResult, FlowyError>; } @@ -43,7 +43,7 @@ pub trait RevisionWebSocket: Send + Sync + 'static { pub struct RevisionWebSocketManager { pub object_name: String, pub object_id: String, - ws_data_sink: Arc, + ws_data_sink: Arc, ws_data_stream: Arc, rev_web_socket: Arc, pub ws_passthrough_tx: Sender, @@ -62,7 +62,7 @@ impl RevisionWebSocketManager { object_name: &str, object_id: &str, rev_web_socket: Arc, - ws_data_sink: Arc, + ws_data_sink: Arc, ws_data_stream: Arc, ping_duration: Duration, ) -> Self { @@ -246,7 +246,7 @@ type SinkStopTx = broadcast::Sender<()>; pub struct RevisionWSSink { object_id: String, object_name: String, - provider: Arc, + provider: Arc, rev_web_socket: Arc, stop_rx: Option, ping_duration: Duration, @@ -256,7 +256,7 @@ impl RevisionWSSink { pub fn new( object_id: &str, object_name: &str, - provider: Arc, + provider: Arc, rev_web_socket: Arc, stop_rx: SinkStopRx, ping_duration: Duration, diff --git a/frontend/rust-lib/flowy-test/src/helper.rs b/frontend/rust-lib/flowy-test/src/helper.rs index 7b090792f3..7d2fc0459d 100644 --- a/frontend/rust-lib/flowy-test/src/helper.rs +++ b/frontend/rust-lib/flowy-test/src/helper.rs @@ -14,7 +14,7 @@ use flowy_user::{ event_map::UserEvent::{InitUser, SignIn, SignOut, SignUp}, }; use lib_dispatch::prelude::{EventDispatcher, ModuleRequest, ToBytes}; -use lib_infra::uuid_string; +use lib_infra::uuid; use std::{fs, path::PathBuf, sync::Arc}; pub struct ViewTest { @@ -118,7 +118,7 @@ pub fn root_dir() -> String { } pub fn random_email() -> String { - format!("{}@appflowy.io", uuid_string()) + format!("{}@appflowy.io", uuid()) } pub fn login_email() -> String { diff --git a/frontend/rust-lib/flowy-test/src/lib.rs b/frontend/rust-lib/flowy-test/src/lib.rs index 6d02f4f973..5e3c9f44dc 100644 --- a/frontend/rust-lib/flowy-test/src/lib.rs +++ b/frontend/rust-lib/flowy-test/src/lib.rs @@ -5,7 +5,7 @@ use crate::helper::*; use flowy_net::{get_client_server_configuration, ClientServerConfiguration}; use flowy_sdk::{FlowySDK, FlowySDKConfig}; use flowy_user::entities::UserProfile; -use lib_infra::uuid_string; +use lib_infra::uuid; pub mod prelude { pub use crate::{event_builder::*, helper::*, *}; @@ -36,7 +36,7 @@ impl std::default::Default for FlowySDKTest { impl FlowySDKTest { pub fn new(server_config: ClientServerConfiguration) -> Self { - let config = FlowySDKConfig::new(&root_dir(), server_config, &uuid_string()).log_filter("trace"); + let config = FlowySDKConfig::new(&root_dir(), server_config, &uuid()).log_filter("trace"); let sdk = std::thread::spawn(|| FlowySDK::new(config)).join().unwrap(); std::mem::forget(sdk.dispatcher()); Self { inner: sdk } diff --git a/frontend/rust-lib/flowy-user/tests/event/user_profile_test.rs b/frontend/rust-lib/flowy-user/tests/event/user_profile_test.rs index 1f29a87a71..c74746090f 100644 --- a/frontend/rust-lib/flowy-user/tests/event/user_profile_test.rs +++ b/frontend/rust-lib/flowy-user/tests/event/user_profile_test.rs @@ -2,7 +2,7 @@ use crate::helper::*; use flowy_test::{event_builder::UserModuleEventBuilder, FlowySDKTest}; use flowy_user::{errors::ErrorCode, event_map::UserEvent::*}; use flowy_user_data_model::entities::{UpdateUserPayload, UserProfile}; -use lib_infra::uuid_string; +use lib_infra::uuid; use serial_test::*; #[tokio::test] @@ -54,7 +54,7 @@ async fn user_update_with_name() { async fn user_update_with_email() { let sdk = FlowySDKTest::default(); let user = sdk.init_user().await; - let new_email = format!("{}@gmail.com", uuid_string()); + let new_email = format!("{}@gmail.com", uuid()); let request = UpdateUserPayload::new(&user.id).email(&new_email); let _ = UserModuleEventBuilder::new(sdk.clone()) .event(UpdateUser) diff --git a/shared-lib/Cargo.lock b/shared-lib/Cargo.lock index 4afa34ed29..3c859d28f0 100644 --- a/shared-lib/Cargo.lock +++ b/shared-lib/Cargo.lock @@ -413,6 +413,7 @@ dependencies = [ "dissimilar", "flowy-derive", "flowy-folder-data-model", + "flowy-grid-data-model", "futures", "lib-infra", "lib-ot", @@ -486,8 +487,11 @@ dependencies = [ "flowy-derive", "lib-infra", "protobuf", + "serde", + "serde_json", "strum", "strum_macros", + "uuid", ] [[package]] diff --git a/shared-lib/flowy-collaboration/Cargo.toml b/shared-lib/flowy-collaboration/Cargo.toml index 3afb107b70..4e36f0832b 100644 --- a/shared-lib/flowy-collaboration/Cargo.toml +++ b/shared-lib/flowy-collaboration/Cargo.toml @@ -10,6 +10,7 @@ lib-ot = { path = "../lib-ot" } lib-infra = { path = "../lib-infra" } flowy-derive = { path = "../flowy-derive" } flowy-folder-data-model = { path = "../flowy-folder-data-model" } +flowy-grid-data-model = { path = "../flowy-grid-data-model" } protobuf = {version = "2.18.0"} bytes = "1.0" log = "0.4.14" diff --git a/shared-lib/flowy-collaboration/src/client_folder/builder.rs b/shared-lib/flowy-collaboration/src/client_folder/builder.rs index c77c6ecf04..22174de348 100644 --- a/shared-lib/flowy-collaboration/src/client_folder/builder.rs +++ b/shared-lib/flowy-collaboration/src/client_folder/builder.rs @@ -41,10 +41,9 @@ impl FolderPadBuilder { // TODO: Reconvert from history if delta.to_str() failed. let folder_json = delta.to_str()?; - let mut folder: FolderPad = serde_json::from_str(&folder_json).map_err(|e| { - CollaborateError::internal().context(format!("Deserialize json to root folder failed: {}", e)) - })?; - folder.root = delta; + let mut folder: FolderPad = serde_json::from_str(&folder_json) + .map_err(|e| CollaborateError::internal().context(format!("Deserialize delta to folder failed: {}", e)))?; + folder.delta = delta; Ok(folder) } @@ -55,11 +54,11 @@ impl FolderPadBuilder { pub(crate) fn build(self) -> CollaborateResult { let json = serde_json::to_string(&self) - .map_err(|e| CollaborateError::internal().context(format!("serial trash to json failed: {}", e)))?; + .map_err(|e| CollaborateError::internal().context(format!("Serialize to folder json str failed: {}", e)))?; Ok(FolderPad { workspaces: self.workspaces, trash: self.trash, - root: PlainTextDeltaBuilder::new().insert(&json).build(), + delta: PlainTextDeltaBuilder::new().insert(&json).build(), }) } } 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 4ce5a11c68..0ecefce257 100644 --- a/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs @@ -1,3 +1,4 @@ +use crate::util::cal_diff; use crate::{ client_folder::builder::FolderPadBuilder, entities::{ @@ -6,9 +7,9 @@ use crate::{ }, errors::{CollaborateError, CollaborateResult}, }; -use dissimilar::*; use flowy_folder_data_model::entities::{app::App, trash::Trash, view::View, workspace::Workspace}; -use lib_ot::core::{FlowyStr, OperationTransformable, PlainTextDelta, PlainTextDeltaBuilder}; +use lib_ot::core::*; +use lib_ot::rich_text::RichTextAttributes; use serde::{Deserialize, Serialize}; use std::sync::Arc; @@ -17,35 +18,7 @@ pub struct FolderPad { pub(crate) workspaces: Vec>, pub(crate) trash: Vec>, #[serde(skip)] - pub(crate) root: FolderDelta, -} - -pub fn default_folder_delta() -> FolderDelta { - PlainTextDeltaBuilder::new() - .insert(r#"{"workspaces":[],"trash":[]}"#) - .build() -} - -pub fn initial_folder_delta(folder_pad: &FolderPad) -> CollaborateResult { - let json = folder_pad.to_json()?; - let delta = PlainTextDeltaBuilder::new().insert(&json).build(); - Ok(delta) -} - -impl std::default::Default for FolderPad { - fn default() -> Self { - FolderPad { - workspaces: vec![], - trash: vec![], - root: default_folder_delta(), - } - } -} - -pub struct FolderChange { - pub delta: FolderDelta, - /// md5: the md5 of the FolderPad's delta after applying the change. - pub md5: String, + pub(crate) delta: FolderDelta, } impl FolderPad { @@ -65,20 +38,20 @@ impl FolderPad { } pub fn delta(&self) -> &FolderDelta { - &self.root + &self.delta } pub fn reset_folder(&mut self, delta: FolderDelta) -> CollaborateResult { let folder = FolderPad::from_delta(delta)?; self.workspaces = folder.workspaces; self.trash = folder.trash; - self.root = folder.root; + self.delta = folder.delta; Ok(self.md5()) } pub fn compose_remote_delta(&mut self, delta: FolderDelta) -> CollaborateResult { - let composed_delta = self.root.compose(&delta)?; + let composed_delta = self.delta.compose(&delta)?; self.reset_folder(composed_delta) } @@ -295,7 +268,7 @@ impl FolderPad { } pub fn md5(&self) -> String { - md5(&self.root.to_bytes()) + md5(&self.delta.to_bytes()) } pub fn to_json(&self) -> CollaborateResult { @@ -315,9 +288,13 @@ impl FolderPad { Some(_) => { let old = cloned_self.to_json()?; let new = self.to_json()?; - let delta = cal_diff(old, new); - self.root = self.root.compose(&delta)?; - Ok(Some(FolderChange { delta, md5: self.md5() })) + match cal_diff::(old, new) { + None => Ok(None), + Some(delta) => { + self.delta = self.delta.compose(&delta)?; + Ok(Some(FolderChange { delta, md5: self.md5() })) + } + } } } } @@ -346,9 +323,13 @@ impl FolderPad { Some(_) => { let old = cloned_self.to_json()?; let new = self.to_json()?; - let delta = cal_diff(old, new); - self.root = self.root.compose(&delta)?; - Ok(Some(FolderChange { delta, md5: self.md5() })) + match cal_diff::(old, new) { + None => Ok(None), + Some(delta) => { + self.delta = self.delta.compose(&delta)?; + Ok(Some(FolderChange { delta, md5: self.md5() })) + } + } } } } @@ -391,23 +372,32 @@ impl FolderPad { } } -fn cal_diff(old: String, new: String) -> PlainTextDelta { - let chunks = dissimilar::diff(&old, &new); - let mut delta_builder = PlainTextDeltaBuilder::new(); - for chunk in &chunks { - match chunk { - Chunk::Equal(s) => { - delta_builder = delta_builder.retain(FlowyStr::from(*s).utf16_size()); - } - Chunk::Delete(s) => { - delta_builder = delta_builder.delete(FlowyStr::from(*s).utf16_size()); - } - Chunk::Insert(s) => { - delta_builder = delta_builder.insert(*s); - } +pub fn default_folder_delta() -> FolderDelta { + PlainTextDeltaBuilder::new() + .insert(r#"{"workspaces":[],"trash":[]}"#) + .build() +} + +pub fn initial_folder_delta(folder_pad: &FolderPad) -> CollaborateResult { + let json = folder_pad.to_json()?; + let delta = PlainTextDeltaBuilder::new().insert(&json).build(); + Ok(delta) +} + +impl std::default::Default for FolderPad { + fn default() -> Self { + FolderPad { + workspaces: vec![], + trash: vec![], + delta: default_folder_delta(), } } - delta_builder.build() +} + +pub struct FolderChange { + pub delta: FolderDelta, + /// md5: the md5 of the FolderPad's delta after applying the change. + pub md5: String, } #[cfg(test)] diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs new file mode 100644 index 0000000000..4919e96470 --- /dev/null +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -0,0 +1,141 @@ +use crate::entities::revision::{md5, Revision}; +use crate::errors::{internal_error, CollaborateError, CollaborateResult}; +use crate::util::{cal_diff, make_delta_from_revisions}; +use flowy_grid_data_model::entities::{CellChangeset, Field, FieldOrder, Grid, RawRow, RowOrder}; +use lib_infra::uuid; +use lib_ot::core::{FlowyStr, OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; +use std::sync::Arc; + +pub type GridDelta = PlainTextDelta; +pub type GridDeltaBuilder = PlainTextDeltaBuilder; + +pub struct GridPad { + pub(crate) grid: Arc, + pub(crate) delta: GridDelta, +} + +impl GridPad { + pub fn from_delta(delta: GridDelta) -> CollaborateResult { + let s = delta.to_str()?; + let grid: Grid = serde_json::from_str(&s) + .map_err(|e| CollaborateError::internal().context(format!("Deserialize delta to grid failed: {}", e)))?; + + Ok(Self { + grid: Arc::new(grid), + delta, + }) + } + + pub fn from_revisions(revisions: Vec) -> CollaborateResult { + let folder_delta: GridDelta = make_delta_from_revisions::(revisions)?; + Self::from_delta(folder_delta) + } + + pub fn create_row(&mut self, row: &RawRow) -> 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); + Ok(Some(())) + }) + } + + 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); + Ok(Some(())) + }) + } + + pub fn delete_row(&mut self, row_id: &str) -> CollaborateResult> { + self.modify_grid( + |grid| match grid.row_orders.iter().position(|row_order| row_order.row_id == row_id) { + None => Ok(None), + Some(index) => { + grid.row_orders.remove(index); + 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(())) + } + } + }) + } + + pub fn md5(&self) -> String { + md5(&self.delta.to_bytes()) + } + + pub fn modify_grid(&mut self, f: F) -> CollaborateResult> + where + F: FnOnce(&mut Grid) -> CollaborateResult>, + { + let cloned_grid = self.grid.clone(); + match f(&mut Arc::make_mut(&mut self.grid))? { + None => Ok(None), + Some(_) => { + let old = json_from_grid(&cloned_grid)?; + let new = json_from_grid(&self.grid)?; + match cal_diff::(old, new) { + None => Ok(None), + Some(delta) => { + self.delta = self.delta.compose(&delta)?; + Ok(Some(GridChange { delta, md5: self.md5() })) + } + } + } + } + } +} + +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) +} + +pub struct GridChange { + pub delta: GridDelta, + /// md5: the md5 of the grid after applying the change. + pub md5: String, +} + +pub fn default_grid_delta(grid: &Grid) -> GridDelta { + let json = serde_json::to_string(&grid).unwrap(); + PlainTextDeltaBuilder::new().insert(&json).build() +} + +impl std::default::Default for GridPad { + fn default() -> Self { + let grid = Grid { + id: uuid(), + field_orders: Default::default(), + row_orders: Default::default(), + }; + let delta = default_grid_delta(&grid); + GridPad { + grid: Arc::new(grid), + delta, + } + } +} diff --git a/shared-lib/flowy-collaboration/src/client_grid/mod.rs b/shared-lib/flowy-collaboration/src/client_grid/mod.rs new file mode 100644 index 0000000000..ee5a403a57 --- /dev/null +++ b/shared-lib/flowy-collaboration/src/client_grid/mod.rs @@ -0,0 +1,3 @@ +mod grid_pad; + +pub use grid_pad::*; diff --git a/shared-lib/flowy-collaboration/src/lib.rs b/shared-lib/flowy-collaboration/src/lib.rs index 801c954605..f690edc4b0 100644 --- a/shared-lib/flowy-collaboration/src/lib.rs +++ b/shared-lib/flowy-collaboration/src/lib.rs @@ -1,5 +1,6 @@ pub mod client_document; pub mod client_folder; +pub mod client_grid; pub mod entities; pub mod errors; pub mod protobuf; diff --git a/shared-lib/flowy-collaboration/src/util.rs b/shared-lib/flowy-collaboration/src/util.rs index 79f7c28fd7..97be40431d 100644 --- a/shared-lib/flowy-collaboration/src/util.rs +++ b/shared-lib/flowy-collaboration/src/util.rs @@ -10,6 +10,8 @@ use crate::{ Revision as RevisionPB, }, }; +use dissimilar::Chunk; +use lib_ot::core::{DeltaBuilder, FlowyStr}; use lib_ot::{ core::{Attributes, Delta, OperationTransformable, NEW_LINE, WHITESPACE}, rich_text::RichTextDelta, @@ -254,3 +256,28 @@ pub fn rev_id_from_str(s: &str) -> Result { .map_err(|e| CollaborateError::internal().context(format!("Parse rev_id from {} failed. {}", s, e)))?; Ok(rev_id) } + +pub fn cal_diff(old: String, new: String) -> Option> { + let chunks = dissimilar::diff(&old, &new); + let mut delta_builder = DeltaBuilder::::new(); + for chunk in &chunks { + match chunk { + Chunk::Equal(s) => { + delta_builder = delta_builder.retain(FlowyStr::from(*s).utf16_size()); + } + Chunk::Delete(s) => { + delta_builder = delta_builder.delete(FlowyStr::from(*s).utf16_size()); + } + Chunk::Insert(s) => { + delta_builder = delta_builder.insert(*s); + } + } + } + + let delta = delta_builder.build(); + if delta.is_empty() { + None + } else { + Some(delta) + } +} diff --git a/shared-lib/flowy-grid-data-model/Cargo.toml b/shared-lib/flowy-grid-data-model/Cargo.toml index 8281121c44..c0e5bb91bc 100644 --- a/shared-lib/flowy-grid-data-model/Cargo.toml +++ b/shared-lib/flowy-grid-data-model/Cargo.toml @@ -11,6 +11,9 @@ protobuf = {version = "2.18.0"} bytes = "1.0" strum = "0.21" strum_macros = "0.21" +serde = { version = "1.0", features = ["derive"] } +serde_json = {version = "1.0"} +uuid = { version = "0.8", features = ["serde", "v4"] } [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 034f823fd2..92ca8006e7 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -1,24 +1,23 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; - use strum_macros::{Display, EnumIter, EnumString}; -#[derive(Debug, Default, ProtoBuf)] +#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)] pub struct Grid { #[pb(index = 1)] pub id: String, #[pb(index = 2)] - pub filters: RepeatedFilter, - - #[pb(index = 3)] + #[serde(flatten)] pub field_orders: RepeatedFieldOrder, - #[pb(index = 4)] + #[pb(index = 3)] + #[serde(flatten)] pub row_orders: RepeatedRowOrder, } -#[derive(Debug, Default, ProtoBuf)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] pub struct FieldOrder { #[pb(index = 1)] pub field_id: String, @@ -27,12 +26,27 @@ pub struct FieldOrder { pub visibility: bool, } -#[derive(Debug, Default, ProtoBuf)] +#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)] pub struct RepeatedFieldOrder { #[pb(index = 1)] + #[serde(rename(serialize = "field_orders", deserialize = "field_orders"))] pub items: Vec, } +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, Default, ProtoBuf)] pub struct Field { #[pb(index = 1)] @@ -63,7 +77,7 @@ pub struct RepeatedField { pub items: Vec, } -#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display)] +#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)] pub enum FieldType { RichText = 0, Number = 1, @@ -130,7 +144,7 @@ impl ToString for AnyData { } } -#[derive(Debug, Default, ProtoBuf)] +#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] pub struct RowOrder { #[pb(index = 1)] pub grid_id: String, @@ -142,12 +156,27 @@ pub struct RowOrder { pub visibility: bool, } -#[derive(Debug, Default, ProtoBuf)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] pub struct RepeatedRowOrder { #[pb(index = 1)] + #[serde(rename(serialize = "row_orders", deserialize = "row_orders"))] 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 + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct RawRow { #[pb(index = 1)] @@ -202,6 +231,21 @@ 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)] @@ -214,20 +258,8 @@ pub struct GridId { pub value: String, } -#[derive(Debug, Default, ProtoBuf)] -pub struct Filter { - #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub name: String, - - #[pb(index = 3)] - pub desc: String, -} - -#[derive(Debug, Default, ProtoBuf)] -pub struct RepeatedFilter { - #[pb(index = 1)] - pub items: Vec, +impl AsRef for GridId { + fn as_ref(&self) -> &str { + &self.value + } } 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 b644b4fd87..1339098bea 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,7 +27,6 @@ pub struct Grid { // message fields pub id: ::std::string::String, - pub filters: ::protobuf::SingularPtrField, pub field_orders: ::protobuf::SingularPtrField, pub row_orders: ::protobuf::SingularPtrField, // special fields @@ -72,40 +71,7 @@ impl Grid { ::std::mem::replace(&mut self.id, ::std::string::String::new()) } - // .RepeatedFilter filters = 2; - - - pub fn get_filters(&self) -> &RepeatedFilter { - self.filters.as_ref().unwrap_or_else(|| ::default_instance()) - } - pub fn clear_filters(&mut self) { - self.filters.clear(); - } - - pub fn has_filters(&self) -> bool { - self.filters.is_some() - } - - // Param is passed by value, moved - pub fn set_filters(&mut self, v: RepeatedFilter) { - self.filters = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_filters(&mut self) -> &mut RepeatedFilter { - if self.filters.is_none() { - self.filters.set_default(); - } - self.filters.as_mut().unwrap() - } - - // Take field - pub fn take_filters(&mut self) -> RepeatedFilter { - self.filters.take().unwrap_or_else(|| RepeatedFilter::new()) - } - - // .RepeatedFieldOrder field_orders = 3; + // .RepeatedFieldOrder field_orders = 2; pub fn get_field_orders(&self) -> &RepeatedFieldOrder { @@ -138,7 +104,7 @@ impl Grid { self.field_orders.take().unwrap_or_else(|| RepeatedFieldOrder::new()) } - // .RepeatedRowOrder row_orders = 4; + // .RepeatedRowOrder row_orders = 3; pub fn get_row_orders(&self) -> &RepeatedRowOrder { @@ -174,11 +140,6 @@ impl Grid { impl ::protobuf::Message for Grid { fn is_initialized(&self) -> bool { - for v in &self.filters { - if !v.is_initialized() { - return false; - } - }; for v in &self.field_orders { if !v.is_initialized() { return false; @@ -200,12 +161,9 @@ 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.filters)?; - }, - 3 => { ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.field_orders)?; }, - 4 => { + 3 => { ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.row_orders)?; }, _ => { @@ -223,10 +181,6 @@ 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.filters.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } if let Some(ref v) = self.field_orders.as_ref() { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; @@ -244,18 +198,13 @@ impl ::protobuf::Message for Grid { if !self.id.is_empty() { os.write_string(1, &self.id)?; } - if let Some(ref v) = self.filters.as_ref() { + if let Some(ref v) = self.field_orders.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.field_orders.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)?; - } if let Some(ref v) = self.row_orders.as_ref() { - os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; } @@ -302,11 +251,6 @@ 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>( - "filters", - |m: &Grid| { &m.filters }, - |m: &mut Grid| { &mut m.filters }, - )); fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "field_orders", |m: &Grid| { &m.field_orders }, @@ -334,7 +278,6 @@ impl ::protobuf::Message for Grid { impl ::protobuf::Clear for Grid { fn clear(&mut self) { self.id.clear(); - self.filters.clear(); self.field_orders.clear(); self.row_orders.clear(); self.unknown_fields.clear(); @@ -3011,6 +2954,291 @@ 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 @@ -3329,415 +3557,6 @@ impl ::protobuf::reflect::ProtobufValue for GridId { } } -#[derive(PartialEq,Clone,Default)] -pub struct Filter { - // message fields - pub id: ::std::string::String, - pub name: ::std::string::String, - pub desc: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Filter { - fn default() -> &'a Filter { - ::default_instance() - } -} - -impl Filter { - pub fn new() -> Filter { - ::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()) - } -} - -impl ::protobuf::Message for Filter { - 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)?; - }, - _ => { - ::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); - } - 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)?; - } - 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() -> Filter { - Filter::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: &Filter| { &m.id }, - |m: &mut Filter| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "name", - |m: &Filter| { &m.name }, - |m: &mut Filter| { &mut m.name }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "desc", - |m: &Filter| { &m.desc }, - |m: &mut Filter| { &mut m.desc }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "Filter", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static Filter { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(Filter::new) - } -} - -impl ::protobuf::Clear for Filter { - fn clear(&mut self) { - self.id.clear(); - self.name.clear(); - self.desc.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Filter { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Filter { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct RepeatedFilter { - // 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 RepeatedFilter { - fn default() -> &'a RepeatedFilter { - ::default_instance() - } -} - -impl RepeatedFilter { - pub fn new() -> RepeatedFilter { - ::std::default::Default::default() - } - - // repeated .Filter items = 1; - - - pub fn get_items(&self) -> &[Filter] { - &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 RepeatedFilter { - 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() -> RepeatedFilter { - RepeatedFilter::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: &RepeatedFilter| { &m.items }, - |m: &mut RepeatedFilter| { &mut m.items }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "RepeatedFilter", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static RepeatedFilter { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(RepeatedFilter::new) - } -} - -impl ::protobuf::Clear for RepeatedFilter { - fn clear(&mut self) { - self.items.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for RepeatedFilter { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for RepeatedFilter { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum FieldType { RichText = 0, @@ -3801,11 +3620,10 @@ impl ::protobuf::reflect::ProtobufValue for FieldType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\ngrid.proto\"\xab\x01\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ - \x02id\x12)\n\x07filters\x18\x02\x20\x01(\x0b2\x0f.RepeatedFilterR\x07fi\ - lters\x126\n\x0cfield_orders\x18\x03\x20\x01(\x0b2\x13.RepeatedFieldOrde\ - rR\x0bfieldOrders\x120\n\nrow_orders\x18\x04\x20\x01(\x0b2\x11.RepeatedR\ - owOrderR\trowOrders\"G\n\nFieldOrder\x12\x19\n\x08field_id\x18\x01\x20\ + \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\ @@ -3835,15 +3653,15 @@ static file_descriptor_proto_data: &'static [u8] = b"\ y\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\"'\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\"@\n\x06Filter\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\"/\n\x0eRepeatedF\ - ilter\x12\x1d\n\x05items\x18\x01\x20\x03(\x0b2\x07.FilterR\x05items*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\ + \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\x08field_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(\tR\x05value*d\n\tFieldType\x12\x0c\n\x08Ric\ + hText\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 16b14f76c9..ee4210c061 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,9 +2,8 @@ syntax = "proto3"; message Grid { string id = 1; - RepeatedFilter filters = 2; - RepeatedFieldOrder field_orders = 3; - RepeatedRowOrder row_orders = 4; + RepeatedFieldOrder field_orders = 2; + RepeatedRowOrder row_orders = 3; } message FieldOrder { string field_id = 1; @@ -60,20 +59,18 @@ message Cell { 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; } message GridId { string value = 1; } -message Filter { - string id = 1; - string name = 2; - string desc = 3; -} -message RepeatedFilter { - repeated Filter items = 1; -} enum FieldType { RichText = 0; Number = 1; diff --git a/shared-lib/flowy-grid-data-model/tests/serde_test.rs b/shared-lib/flowy-grid-data-model/tests/serde_test.rs new file mode 100644 index 0000000000..7024b054d8 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/tests/serde_test.rs @@ -0,0 +1,58 @@ +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 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); + assert_eq!( + json, + r#"{"id":"1","field_orders":[{"field_id":"1","visibility":false}],"row_orders":[{"grid_id":"1","row_id":"1","visibility":false}]}"# + ) +} + +#[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 json = serde_json::to_string(&grid).unwrap(); + assert_eq!(json, r#"{"id":"1","field_orders":[],"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 uuid() -> String { + uuid::Uuid::new_v4().to_string() +} diff --git a/shared-lib/lib-infra/src/lib.rs b/shared-lib/lib-infra/src/lib.rs index ba8b17c7b5..4cc32f06b7 100644 --- a/shared-lib/lib-infra/src/lib.rs +++ b/shared-lib/lib-infra/src/lib.rs @@ -3,7 +3,7 @@ pub mod future; pub mod retry; #[allow(dead_code)] -pub fn uuid_string() -> String { +pub fn uuid() -> String { uuid::Uuid::new_v4().to_string() } From 9125db7ef0d39c15fc3ea3033dde279023a8bf4d Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 4 Mar 2022 21:26:32 +0800 Subject: [PATCH 09/17] feat: config grid editor --- frontend/rust-lib/Cargo.lock | 2 +- .../2021-09-22-074638_flowy-doc-op/down.sql | 3 +- .../2022-03-04-101530_flowy-grid/down.sql | 2 + .../2022-03-04-101530_flowy-grid/up.sql | 5 + frontend/rust-lib/flowy-database/src/lib.rs | 8 +- .../rust-lib/flowy-database/src/schema.rs | 8 + frontend/rust-lib/flowy-grid/Cargo.toml | 5 +- .../flowy-grid/src/services/grid_editor.rs | 36 ++-- .../flowy-grid/src/services/kv_persistence.rs | 167 ++++++++++++++++++ .../rust-lib/flowy-grid/src/services/mod.rs | 2 +- .../flowy-grid/src/services/row_kv.rs | 95 ---------- .../flowy-net/src/http_server/document.rs | 2 +- .../src/client_grid/grid_pad.rs | 15 +- 13 files changed, 222 insertions(+), 128 deletions(-) create mode 100644 frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql create mode 100644 frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql create mode 100644 frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs delete mode 100644 frontend/rust-lib/flowy-grid/src/services/row_kv.rs diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index c4aa021bdc..199389951d 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1049,12 +1049,12 @@ dependencies = [ name = "flowy-grid" version = "0.1.0" dependencies = [ - "async-trait", "bytes", "chrono", "dart-notify", "diesel", "flowy-collaboration", + "flowy-database", "flowy-derive", "flowy-error", "flowy-grid-data-model", diff --git a/frontend/rust-lib/flowy-database/migrations/2021-09-22-074638_flowy-doc-op/down.sql b/frontend/rust-lib/flowy-database/migrations/2021-09-22-074638_flowy-doc-op/down.sql index 291a97c5ce..3f706119bd 100644 --- a/frontend/rust-lib/flowy-database/migrations/2021-09-22-074638_flowy-doc-op/down.sql +++ b/frontend/rust-lib/flowy-database/migrations/2021-09-22-074638_flowy-doc-op/down.sql @@ -1 +1,2 @@ --- This file should undo anything in `up.sql` \ No newline at end of file +-- This file should undo anything in `up.sql` +DROP TABLE rev_table; \ No newline at end of file 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 new file mode 100644 index 0000000000..96473ec177 --- /dev/null +++ b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +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 new file mode 100644 index 0000000000..edde5d7dfa --- /dev/null +++ b/frontend/rust-lib/flowy-database/migrations/2022-03-04-101530_flowy-grid/up.sql @@ -0,0 +1,5 @@ +-- Your SQL goes here +CREATE TABLE kv_table ( + key TEXT NOT NULL PRIMARY KEY, + value BLOB NOT NULL DEFAULT (x'') +); \ No newline at end of file diff --git a/frontend/rust-lib/flowy-database/src/lib.rs b/frontend/rust-lib/flowy-database/src/lib.rs index bfdec920d4..e6c7d0b492 100644 --- a/frontend/rust-lib/flowy-database/src/lib.rs +++ b/frontend/rust-lib/flowy-database/src/lib.rs @@ -6,12 +6,10 @@ pub mod kv; use lib_sqlite::PoolConfig; pub use lib_sqlite::{ConnectionPool, DBConnection, Database}; - pub mod schema; #[macro_use] pub mod macros; - #[macro_use] extern crate diesel; #[macro_use] @@ -20,11 +18,11 @@ extern crate diesel_derives; extern crate diesel_migrations; pub type Error = diesel::result::Error; - pub mod prelude { - pub use diesel::{query_dsl::*, BelongingToDsl, ExpressionMethods, RunQueryDsl}; - pub use super::UserDatabaseConnection; + pub use crate::*; + pub use diesel::SqliteConnection; + pub use diesel::{query_dsl::*, BelongingToDsl, ExpressionMethods, RunQueryDsl}; } embed_migrations!("../flowy-database/migrations/"); diff --git a/frontend/rust-lib/flowy-database/src/schema.rs b/frontend/rust-lib/flowy-database/src/schema.rs index 0bc8b99ef8..aa7200000e 100644 --- a/frontend/rust-lib/flowy-database/src/schema.rs +++ b/frontend/rust-lib/flowy-database/src/schema.rs @@ -21,6 +21,13 @@ table! { } } +table! { + kv_table (key) { + key -> Text, + value -> Binary, + } +} + table! { rev_table (id) { id -> Integer, @@ -84,6 +91,7 @@ table! { allow_tables_to_appear_in_same_query!( app_table, doc_table, + kv_table, rev_table, trash_table, user_table, diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index 6258f9cc80..237ff3f6ea 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -10,12 +10,13 @@ lib-dispatch = { path = "../lib-dispatch" } dart-notify = { path = "../dart-notify" } lib-sqlite = { path = "../lib-sqlite" } flowy-sync = { path = "../flowy-sync" } -flowy-error = { path = "../flowy-error"} +flowy-error = { path = "../flowy-error", features = ["db"]} flowy-derive = { path = "../../../shared-lib/flowy-derive" } lib-ot = { path = "../../../shared-lib/lib-ot" } lib-infra = { path = "../../../shared-lib/lib-infra" } flowy-grid-data-model = { path = "../../../shared-lib/flowy-grid-data-model" } flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration" } +flowy-database = { path = "../flowy-database" } strum = "0.21" strum_macros = "0.21" @@ -27,8 +28,8 @@ lazy_static = "1.4.0" chrono = "0.4.19" uuid = { version = "0.8", features = ["serde", "v4"] } bytes = { version = "1.0" } -async-trait = "0.1.52" diesel = {version = "1.4.8", features = ["sqlite"]} +#diesel_derives = {version = "1.4.1", features = ["sqlite"]} parking_lot = "0.11" 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 a97230f851..b96e11b749 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,9 +1,9 @@ -use crate::services::row_kv::{RowKVPersistence, RowKVTransaction}; +use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use flowy_collaboration::client_grid::{GridChange, GridPad}; 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::{GridId, RawRow}; +use flowy_grid_data_model::entities::{Field, GridId, RawRow}; use flowy_sync::{ RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder, RevisionPersistence, RevisionWebSocket, RevisionWebSocketManager, @@ -19,7 +19,7 @@ pub struct ClientGridEditor { grid_id: GridId, grid: Arc>, rev_manager: Arc, - kv: Arc, + kv: Arc, } impl ClientGridEditor { @@ -39,7 +39,7 @@ impl ClientGridEditor { rev_manager.load::(cloud).await?, )); let rev_manager = Arc::new(rev_manager); - let kv = Arc::new(RowKVPersistence::new(pool)); + let kv = Arc::new(GridKVPersistence::new(pool)); let user_id = user_id.to_owned(); let grid_id = grid_id.to_owned(); @@ -53,18 +53,30 @@ impl ClientGridEditor { } pub async fn create_row(&self, row: RawRow) -> FlowyResult<()> { - let _ = self - .modify(|grid| { - let change = grid.create_row(&row)?; - Ok(change) - }) - .await?; - + let _ = self.modify(|grid| Ok(grid.create_row(&row)?)).await?; let _ = self.kv.set(row)?; Ok(()) } - pub async fn modify(&self, f: F) -> FlowyResult<()> + 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 create_field(&mut self, field: Field) -> FlowyResult<()> { + let _ = self.modify(|grid| Ok(grid.create_field(&field)?)).await?; + let _ = self.kv.set(field)?; + Ok(()) + } + + 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(()) + } + + async fn modify(&self, f: F) -> FlowyResult<()> where F: FnOnce(&mut GridPad) -> FlowyResult>, { diff --git a/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs b/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs new file mode 100644 index 0000000000..3538af16f9 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs @@ -0,0 +1,167 @@ +use ::diesel::{query_dsl::*, ExpressionMethods}; +use bytes::Bytes; +use diesel::SqliteConnection; +use flowy_database::{ + prelude::*, + schema::{kv_table, kv_table::dsl}, +}; +use flowy_error::{FlowyError, FlowyResult}; +use flowy_grid_data_model::entities::{Field, RawRow}; +use lib_infra::future::{BoxResultFuture, FutureResult}; +use lib_sqlite::{ConnectionManager, ConnectionPool}; +use std::sync::Arc; + +#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] +#[table_name = "kv_table"] +#[primary_key(key)] +pub struct KeyValue { + key: String, + value: Vec, +} + +pub trait KVTransaction { + fn get>(&self, key: &str) -> FlowyResult>; + fn set>(&self, value: T) -> FlowyResult<()>; + fn remove(&self, key: &str) -> FlowyResult<()>; + + fn batch_get>(&self, keys: Vec) -> FlowyResult>; + fn batch_set>(&self, values: Vec) -> FlowyResult<()>; + fn batch_remove(&self, keys: Vec) -> FlowyResult<()>; +} + +pub struct GridKVPersistence { + pool: Arc, +} + +impl GridKVPersistence { + pub fn new(pool: Arc) -> Self { + Self { pool } + } + + pub fn begin_transaction(&self, f: F) -> FlowyResult + where + F: for<'a> FnOnce(SqliteTransaction<'a>) -> FlowyResult, + { + let conn = self.pool.get()?; + conn.immediate_transaction::<_, FlowyError, _>(|| { + let sql_transaction = SqliteTransaction { conn: &conn }; + f(sql_transaction) + }) + } +} + +impl KVTransaction for GridKVPersistence { + fn get>(&self, key: &str) -> FlowyResult> { + self.begin_transaction(|transaction| transaction.get(key)) + } + + fn set>(&self, value: T) -> FlowyResult<()> { + self.begin_transaction(|transaction| transaction.set(value)) + } + + fn remove(&self, key: &str) -> FlowyResult<()> { + self.begin_transaction(|transaction| transaction.remove(key)) + } + + fn batch_get>(&self, keys: Vec) -> FlowyResult> { + self.begin_transaction(|transaction| transaction.batch_get(keys)) + } + + fn batch_set>(&self, values: Vec) -> FlowyResult<()> { + self.begin_transaction(|transaction| transaction.batch_set(values)) + } + + fn batch_remove(&self, keys: Vec) -> FlowyResult<()> { + self.begin_transaction(|transaction| transaction.batch_remove(keys)) + } +} + +pub struct SqliteTransaction<'a> { + conn: &'a SqliteConnection, +} + +impl<'a> KVTransaction for SqliteTransaction<'a> { + fn get>(&self, key: &str) -> FlowyResult> { + let item = dsl::kv_table + .filter(kv_table::key.eq(key)) + .first::(self.conn)?; + let value: T = item.try_into()?; + Ok(Some(value)) + } + + fn set>(&self, value: T) -> FlowyResult<()> { + let item: KeyValue = value.into(); + let _ = diesel::replace_into(kv_table::table).values(&item).execute(self.conn)?; + Ok(()) + } + + fn remove(&self, key: &str) -> FlowyResult<()> { + let sql = dsl::kv_table.filter(kv_table::key.eq(key)); + let _ = diesel::delete(sql).execute(self.conn)?; + Ok(()) + } + + fn batch_get>(&self, keys: Vec) -> FlowyResult> { + let items = dsl::kv_table + .filter(kv_table::key.eq_any(&keys)) + .load::(self.conn)?; + let mut values = vec![]; + for item in items { + let value: T = item.try_into()?; + values.push(value); + } + Ok(values) + } + + fn batch_set>(&self, values: Vec) -> FlowyResult<()> { + let items = values.into_iter().map(|value| value.into()).collect::>(); + let _ = diesel::replace_into(kv_table::table) + .values(&items) + .execute(self.conn)?; + Ok(()) + } + + fn batch_remove(&self, keys: Vec) -> FlowyResult<()> { + let sql = dsl::kv_table.filter(kv_table::key.eq_any(keys)); + let _ = diesel::delete(sql).execute(self.conn)?; + Ok(()) + } +} + +impl std::convert::From for KeyValue { + fn from(row: RawRow) -> Self { + let key = row.id.clone(); + let bytes: Bytes = row.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::From for KeyValue { + fn from(field: Field) -> Self { + let key = field.id.clone(); + let bytes: Bytes = field.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); + Field::try_from(bytes) + .map_err(|e| FlowyError::internal().context(format!("Deserialize into field failed: {:?}", e))) + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index 48cb2faf89..0d9cae4f1c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -3,6 +3,6 @@ mod util; pub mod cell_data; pub mod grid_editor; -mod row_kv; +mod kv_persistence; pub use stringify::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/row_kv.rs b/frontend/rust-lib/flowy-grid/src/services/row_kv.rs deleted file mode 100644 index 11f380fe16..0000000000 --- a/frontend/rust-lib/flowy-grid/src/services/row_kv.rs +++ /dev/null @@ -1,95 +0,0 @@ -use async_trait::async_trait; -use diesel::SqliteConnection; -use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::RawRow; -use lib_infra::future::{BoxResultFuture, FutureResult}; -use lib_sqlite::{ConnectionManager, ConnectionPool}; -use std::sync::Arc; - -pub trait RowKVTransaction { - fn get(&self, row_id: &str) -> FlowyResult>; - fn set(&self, row: RawRow) -> FlowyResult<()>; - fn remove(&self, row_id: &str) -> FlowyResult<()>; - - fn batch_get(&self, ids: Vec) -> FlowyResult<()>; - fn batch_set(&self, rows: Vec) -> FlowyResult<()>; - fn batch_delete(&self, ids: Vec) -> FlowyResult<()>; -} - -pub struct RowKVPersistence { - pool: Arc, -} - -impl RowKVPersistence { - pub fn new(pool: Arc) -> Self { - Self { pool } - } - - pub fn begin_transaction(&self, f: F) -> FlowyResult - where - F: for<'a> FnOnce(Box) -> FlowyResult, - { - let conn = self.pool.get()?; - conn.immediate_transaction::<_, FlowyError, _>(|| { - let sql_transaction = SqliteTransaction { conn: &conn }; - f(Box::new(sql_transaction)) - }) - } -} - -impl RowKVTransaction for RowKVPersistence { - fn get(&self, row_id: &str) -> FlowyResult> { - self.begin_transaction(|transaction| transaction.get(row_id)) - } - - fn set(&self, row: RawRow) -> FlowyResult<()> { - self.begin_transaction(|transaction| transaction.set(row)) - } - - fn remove(&self, row_id: &str) -> FlowyResult<()> { - self.begin_transaction(|transaction| transaction.remove(row_id)) - } - - fn batch_get(&self, ids: Vec) -> FlowyResult<()> { - self.begin_transaction(|transaction| transaction.batch_get(ids)) - } - - fn batch_set(&self, rows: Vec) -> FlowyResult<()> { - self.begin_transaction(|transaction| transaction.batch_set(rows)) - } - - fn batch_delete(&self, ids: Vec) -> FlowyResult<()> { - self.begin_transaction(|transaction| transaction.batch_delete(ids)) - } -} - -pub struct SqliteTransaction<'a> { - conn: &'a SqliteConnection, -} - -#[async_trait] -impl<'a> RowKVTransaction for SqliteTransaction<'a> { - fn get(&self, row_id: &str) -> FlowyResult> { - todo!() - } - - fn set(&self, row: RawRow) -> FlowyResult<()> { - todo!() - } - - fn remove(&self, row_id: &str) -> FlowyResult<()> { - todo!() - } - - fn batch_get(&self, ids: Vec) -> FlowyResult<()> { - todo!() - } - - fn batch_set(&self, rows: Vec) -> FlowyResult<()> { - todo!() - } - - fn batch_delete(&self, ids: Vec) -> FlowyResult<()> { - todo!() - } -} 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 e5be5ef6da..da33e1b8a0 100644 --- a/frontend/rust-lib/flowy-net/src/http_server/document.rs +++ b/frontend/rust-lib/flowy-net/src/http_server/document.rs @@ -2,8 +2,8 @@ use crate::{ configuration::*, request::{HttpRequestBuilder, ResponseMiddleware}, }; +use flowy_block::BlockCloudService; use flowy_collaboration::entities::document_info::{BlockId, BlockInfo, CreateBlockParams, ResetBlockParams}; -use flowy_document::BlockCloudService; use flowy_error::FlowyError; use http_flowy::response::FlowyResponse; use lazy_static::lazy_static; 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 4919e96470..0d6eab93f2 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -54,16 +54,11 @@ impl GridPad { }) } - pub fn delete_row(&mut self, row_id: &str) -> CollaborateResult> { - self.modify_grid( - |grid| match grid.row_orders.iter().position(|row_order| row_order.row_id == row_id) { - None => Ok(None), - Some(index) => { - grid.row_orders.remove(index); - Ok(Some(())) - } - }, - ) + pub fn delete_rows(&mut self, row_ids: &Vec) -> CollaborateResult> { + self.modify_grid(|grid| { + grid.row_orders.retain(|row_order| !row_ids.contains(&row_order.row_id)); + Ok(Some(())) + }) } pub fn delete_field(&mut self, field_id: &str) -> CollaborateResult> { From d0b457c00749f695a08af1336eadae18f9e680d8 Mon Sep 17 00:00:00 2001 From: appflowy Date: Fri, 4 Mar 2022 22:09:16 +0800 Subject: [PATCH 10/17] feat: integrate grid into flowy-sdk --- .../lib/protobuf/lib-ws/msg.pbenum.dart | 2 + .../lib/protobuf/lib-ws/msg.pbjson.dart | 3 +- frontend/rust-lib/Cargo.lock | 1 + frontend/rust-lib/flowy-block/src/manager.rs | 4 +- frontend/rust-lib/flowy-grid/Cargo.toml | 2 +- .../rust-lib/flowy-grid/src/controller.rs | 1 - .../rust-lib/flowy-grid/src/event_handler.rs | 2 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 2 +- frontend/rust-lib/flowy-grid/src/lib.rs | 4 +- frontend/rust-lib/flowy-grid/src/manager.rs | 107 ++++++++++++++++++ .../flowy-grid/src/services/grid_editor.rs | 14 +-- .../flowy-net/src/local_server/server.rs | 3 + .../flowy-sdk/src/deps_resolve/block_deps.rs | 4 +- .../flowy-sdk/src/deps_resolve/grid_deps.rs | 66 +++++++++++ .../flowy-sdk/src/deps_resolve/mod.rs | 3 + .../flowy-sdk/src/deps_resolve/util.rs | 0 frontend/rust-lib/flowy-sdk/src/lib.rs | 17 ++- frontend/rust-lib/flowy-sdk/src/module.rs | 13 ++- shared-lib/lib-ws/src/msg.rs | 3 + shared-lib/lib-ws/src/protobuf/model/msg.rs | 7 +- .../lib-ws/src/protobuf/proto/msg.proto | 1 + 21 files changed, 233 insertions(+), 26 deletions(-) delete mode 100644 frontend/rust-lib/flowy-grid/src/controller.rs create mode 100644 frontend/rust-lib/flowy-grid/src/manager.rs create mode 100644 frontend/rust-lib/flowy-sdk/src/deps_resolve/grid_deps.rs create mode 100644 frontend/rust-lib/flowy-sdk/src/deps_resolve/util.rs diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/lib-ws/msg.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/lib-ws/msg.pbenum.dart index bca822dca5..ffcdcc93ac 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/lib-ws/msg.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/lib-ws/msg.pbenum.dart @@ -12,10 +12,12 @@ import 'package:protobuf/protobuf.dart' as $pb; class WSChannel extends $pb.ProtobufEnum { static const WSChannel Document = WSChannel._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Document'); static const WSChannel Folder = WSChannel._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Folder'); + static const WSChannel Grid = WSChannel._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Grid'); static const $core.List values = [ Document, Folder, + Grid, ]; static final $core.Map<$core.int, WSChannel> _byValue = $pb.ProtobufEnum.initByValue(values); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/lib-ws/msg.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/lib-ws/msg.pbjson.dart index d1edecb666..0b878758fa 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/lib-ws/msg.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/lib-ws/msg.pbjson.dart @@ -14,11 +14,12 @@ const WSChannel$json = const { '2': const [ const {'1': 'Document', '2': 0}, const {'1': 'Folder', '2': 1}, + const {'1': 'Grid', '2': 2}, ], }; /// Descriptor for `WSChannel`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List wSChannelDescriptor = $convert.base64Decode('CglXU0NoYW5uZWwSDAoIRG9jdW1lbnQQABIKCgZGb2xkZXIQAQ=='); +final $typed_data.Uint8List wSChannelDescriptor = $convert.base64Decode('CglXU0NoYW5uZWwSDAoIRG9jdW1lbnQQABIKCgZGb2xkZXIQARIICgRHcmlkEAI='); @$core.Deprecated('Use webSocketRawMessageDescriptor instead') const WebSocketRawMessage$json = const { '1': 'WebSocketRawMessage', diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 199389951d..f5ae68cbda 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1052,6 +1052,7 @@ dependencies = [ "bytes", "chrono", "dart-notify", + "dashmap", "diesel", "flowy-collaboration", "flowy-database", diff --git a/frontend/rust-lib/flowy-block/src/manager.rs b/frontend/rust-lib/flowy-block/src/manager.rs index e7ad6f7494..6c9e23b4ed 100644 --- a/frontend/rust-lib/flowy-block/src/manager.rs +++ b/frontend/rust-lib/flowy-block/src/manager.rs @@ -32,11 +32,11 @@ impl BlockManager { block_user: Arc, rev_web_socket: Arc, ) -> Self { - let block_handlers = Arc::new(BlockEditors::new()); + let block_editors = Arc::new(BlockEditors::new()); Self { cloud_service, rev_web_socket, - block_editors: block_handlers, + block_editors, block_user, } } diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index 237ff3f6ea..5c65fc5ebc 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -29,7 +29,7 @@ chrono = "0.4.19" uuid = { version = "0.8", features = ["serde", "v4"] } bytes = { version = "1.0" } diesel = {version = "1.4.8", features = ["sqlite"]} -#diesel_derives = {version = "1.4.1", features = ["sqlite"]} +dashmap = "4.0" parking_lot = "0.11" diff --git a/frontend/rust-lib/flowy-grid/src/controller.rs b/frontend/rust-lib/flowy-grid/src/controller.rs deleted file mode 100644 index acbe116978..0000000000 --- a/frontend/rust-lib/flowy-grid/src/controller.rs +++ /dev/null @@ -1 +0,0 @@ -pub struct GridManager {} diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 600f55ab1a..7d6e7f8e21 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,4 +1,4 @@ -use crate::controller::GridManager; +use crate::manager::GridManager; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ CreateGridPayload, Grid, GridId, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 3fce720d36..787cd6336d 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -1,5 +1,5 @@ -use crate::controller::GridManager; use crate::event_handler::*; +use crate::manager::GridManager; use flowy_derive::{Flowy_Event, ProtoBuf_Enum}; use lib_dispatch::prelude::*; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-grid/src/lib.rs b/frontend/rust-lib/flowy-grid/src/lib.rs index 2645d2b121..a7b1a080e7 100644 --- a/frontend/rust-lib/flowy-grid/src/lib.rs +++ b/frontend/rust-lib/flowy-grid/src/lib.rs @@ -1,9 +1,9 @@ #[macro_use] mod macros; -mod controller; mod event_handler; -mod event_map; +pub mod event_map; +pub mod manager; mod protobuf; mod services; diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs new file mode 100644 index 0000000000..af4de88293 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -0,0 +1,107 @@ +use crate::services::grid_editor::ClientGridEditor; +use dashmap::DashMap; +use flowy_error::{FlowyError, FlowyResult}; +use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; +use lib_sqlite::ConnectionPool; +use std::sync::Arc; + +pub trait GridUser: Send + Sync { + fn user_id(&self) -> Result; + fn token(&self) -> Result; + fn db_pool(&self) -> Result, FlowyError>; +} + +pub struct GridManager { + grid_editors: Arc, + grid_user: Arc, + rev_web_socket: Arc, +} + +impl GridManager { + pub fn new(grid_user: Arc, rev_web_socket: Arc) -> Self { + let grid_editors = Arc::new(GridEditors::new()); + Self { + grid_editors, + grid_user, + rev_web_socket, + } + } + + #[tracing::instrument(level = "debug", skip(self, grid_id), fields(grid_id), err)] + pub async fn open_grid>(&self, grid_id: T) -> Result, FlowyError> { + let grid_id = grid_id.as_ref(); + tracing::Span::current().record("grid_id", &grid_id); + self.get_grid_editor(grid_id).await + } + + #[tracing::instrument(level = "trace", skip(self, grid_id), fields(grid_id), err)] + pub fn close_grid>(&self, grid_id: T) -> Result<(), FlowyError> { + let grid_id = grid_id.as_ref(); + tracing::Span::current().record("grid_id", &grid_id); + self.grid_editors.remove(grid_id); + Ok(()) + } + + #[tracing::instrument(level = "debug", skip(self, grid_id), fields(doc_id), err)] + pub fn delete_grid>(&self, grid_id: T) -> Result<(), FlowyError> { + let grid_id = grid_id.as_ref(); + tracing::Span::current().record("grid_id", &grid_id); + self.grid_editors.remove(grid_id); + Ok(()) + } + + async fn get_grid_editor(&self, grid_id: &str) -> FlowyResult> { + match self.grid_editors.get(grid_id) { + None => { + let db_pool = self.grid_user.db_pool()?; + self.make_grid_editor(grid_id, db_pool).await + } + Some(editor) => Ok(editor), + } + } + + async fn make_grid_editor( + &self, + grid_id: &str, + pool: Arc, + ) -> Result, FlowyError> { + let token = self.grid_user.token()?; + let user_id = self.grid_user.user_id()?; + let grid_editor = ClientGridEditor::new(&user_id, grid_id, &token, pool, self.rev_web_socket.clone()).await?; + self.grid_editors.insert(grid_id, &grid_editor); + Ok(grid_editor) + } +} + +pub struct GridEditors { + inner: DashMap>, +} + +impl GridEditors { + fn new() -> Self { + Self { inner: DashMap::new() } + } + + pub(crate) fn insert(&self, grid_id: &str, grid_editor: &Arc) { + if self.inner.contains_key(grid_id) { + tracing::warn!("Grid:{} already exists in cache", grid_id); + } + self.inner.insert(grid_id.to_string(), grid_editor.clone()); + } + + pub(crate) fn contains(&self, grid_id: &str) -> bool { + self.inner.get(grid_id).is_some() + } + + pub(crate) fn get(&self, grid_id: &str) -> Option> { + if !self.contains(grid_id) { + return None; + } + let opened_grid = self.inner.get(grid_id).unwrap(); + Some(opened_grid.clone()) + } + + pub(crate) fn remove(&self, grid_id: &str) { + self.inner.remove(grid_id); + } +} 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 b96e11b749..974c026069 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -16,7 +16,7 @@ use std::sync::Arc; pub struct ClientGridEditor { user_id: String, - grid_id: GridId, + grid_id: String, grid: Arc>, rev_manager: Arc, kv: Arc, @@ -25,13 +25,13 @@ pub struct ClientGridEditor { impl ClientGridEditor { pub async fn new( user_id: &str, - grid_id: &GridId, + grid_id: &str, token: &str, pool: Arc, _web_socket: Arc, - ) -> FlowyResult { - let rev_persistence = Arc::new(RevisionPersistence::new(user_id, grid_id.as_ref(), pool.clone())); - let mut rev_manager = RevisionManager::new(user_id, grid_id.as_ref(), rev_persistence); + ) -> FlowyResult> { + let rev_persistence = Arc::new(RevisionPersistence::new(user_id, grid_id, pool.clone())); + let mut rev_manager = RevisionManager::new(user_id, grid_id, rev_persistence); let cloud = Arc::new(GridRevisionCloudService { token: token.to_string(), }); @@ -43,13 +43,13 @@ impl ClientGridEditor { let user_id = user_id.to_owned(); let grid_id = grid_id.to_owned(); - Ok(Self { + Ok(Arc::new(Self { user_id, grid_id, grid, rev_manager, kv, - }) + })) } pub async fn create_row(&self, row: RawRow) -> FlowyResult<()> { 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 24fda76639..a9149720fb 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/server.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/server.rs @@ -122,6 +122,9 @@ impl LocalWebSocketRunner { let _ = self.handle_folder_client_data(client_data, "".to_owned()).await?; Ok(()) } + WSChannel::Grid => { + todo!("Implement grid web socket channel") + } } } diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/block_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/block_deps.rs index c7e77e252c..f8c97d133c 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/block_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/block_deps.rs @@ -25,13 +25,13 @@ impl BlockDepsResolver { server_config: &ClientServerConfiguration, ) -> Arc { let user = Arc::new(BlockUserImpl(user_session)); - let ws_sender = Arc::new(BlockWebSocket(ws_conn.clone())); + let rev_web_socket = Arc::new(BlockWebSocket(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, ws_sender)); + let manager = Arc::new(BlockManager::new(cloud_service, user, rev_web_socket)); let receiver = Arc::new(DocumentWSMessageReceiverImpl(manager.clone())); ws_conn.add_ws_message_receiver(receiver).unwrap(); diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/grid_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/grid_deps.rs new file mode 100644 index 0000000000..26eb87ecbc --- /dev/null +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/grid_deps.rs @@ -0,0 +1,66 @@ +use crate::FlowyError; +use bytes::Bytes; +use flowy_collaboration::entities::ws_data::ClientRevisionWSData; +use flowy_database::ConnectionPool; +use flowy_grid::manager::{GridManager, GridUser}; +use flowy_net::ws::connection::FlowyWebSocketConnect; +use flowy_sync::{RevisionWebSocket, WSStateReceiver}; +use flowy_user::services::UserSession; +use futures_core::future::BoxFuture; +use lib_infra::future::BoxResultFuture; +use lib_ws::{WSChannel, WebSocketRawMessage}; +use std::convert::TryInto; +use std::sync::Arc; + +pub struct GridDepsResolver(); + +impl GridDepsResolver { + pub fn resolve(ws_conn: Arc, user_session: Arc) -> Arc { + let user = Arc::new(GridUserImpl(user_session)); + let rev_web_socket = Arc::new(GridWebSocket(ws_conn.clone())); + let manager = Arc::new(GridManager::new(user, rev_web_socket)); + manager + } +} + +struct GridUserImpl(Arc); +impl GridUser for GridUserImpl { + fn user_id(&self) -> Result { + self.0.user_id() + } + + fn token(&self) -> Result { + self.0.token() + } + + fn db_pool(&self) -> Result, FlowyError> { + self.0.db_pool() + } +} + +struct GridWebSocket(Arc); +impl RevisionWebSocket for GridWebSocket { + fn send(&self, data: ClientRevisionWSData) -> BoxResultFuture<(), FlowyError> { + let bytes: Bytes = data.try_into().unwrap(); + let msg = WebSocketRawMessage { + channel: WSChannel::Grid, + data: bytes.to_vec(), + }; + + let ws_conn = self.0.clone(); + Box::pin(async move { + match ws_conn.web_socket().await? { + None => {} + Some(sender) => { + sender.send(msg).map_err(|e| FlowyError::internal().context(e))?; + } + } + Ok(()) + }) + } + + fn subscribe_state_changed(&self) -> BoxFuture { + let ws_conn = self.0.clone(); + Box::pin(async move { ws_conn.subscribe_websocket_state().await }) + } +} 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 569c32b8de..c0a84d8d94 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/mod.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/mod.rs @@ -1,7 +1,10 @@ mod block_deps; mod folder_deps; +mod grid_deps; mod user_deps; +mod util; pub use block_deps::*; pub use folder_deps::*; +pub use grid_deps::*; pub use user_deps::*; diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/util.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/util.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index a24c071943..5ea59b176d 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -5,6 +5,7 @@ pub use flowy_net::get_client_server_configuration; use crate::deps_resolve::*; use flowy_block::BlockManager; use flowy_folder::{controller::FolderManager, errors::FlowyError}; +use flowy_grid::manager::GridManager; use flowy_net::ClientServerConfiguration; use flowy_net::{ entities::NetworkType, @@ -88,6 +89,7 @@ pub struct FlowySDK { pub user_session: Arc, pub document_manager: Arc, pub folder_manager: Arc, + pub grid_manager: Arc, pub dispatcher: Arc, pub ws_conn: Arc, pub local_server: Option>, @@ -100,7 +102,7 @@ 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, document_manager, folder_manager, local_server) = runtime.block_on(async { + let (user_session, document_manager, folder_manager, local_server, grid_manager) = runtime.block_on(async { let user_session = mk_user_session(&config, &local_server, &config.server_config); let document_manager = BlockDepsResolver::resolve( local_server.clone(), @@ -118,15 +120,23 @@ impl FlowySDK { ) .await; + let grid_manager = GridDepsResolver::resolve(ws_conn.clone(), user_session.clone()); + if let Some(local_server) = local_server.as_ref() { local_server.run(); } ws_conn.init().await; - (user_session, document_manager, folder_manager, local_server) + ( + user_session, + document_manager, + folder_manager, + local_server, + grid_manager, + ) }); let dispatcher = Arc::new(EventDispatcher::construct(runtime, || { - mk_modules(&ws_conn, &folder_manager, &user_session) + mk_modules(&ws_conn, &folder_manager, &grid_manager, &user_session) })); _start_listening(&dispatcher, &ws_conn, &user_session, &folder_manager); @@ -136,6 +146,7 @@ impl FlowySDK { user_session, document_manager, folder_manager, + grid_manager, dispatcher, ws_conn, local_server, diff --git a/frontend/rust-lib/flowy-sdk/src/module.rs b/frontend/rust-lib/flowy-sdk/src/module.rs index b88300d529..27d9c8dd8c 100644 --- a/frontend/rust-lib/flowy-sdk/src/module.rs +++ b/frontend/rust-lib/flowy-sdk/src/module.rs @@ -1,4 +1,5 @@ use flowy_folder::controller::FolderManager; +use flowy_grid::manager::GridManager; use flowy_net::ws::connection::FlowyWebSocketConnect; use flowy_user::services::UserSession; use lib_dispatch::prelude::Module; @@ -7,22 +8,28 @@ use std::sync::Arc; pub fn mk_modules( ws_conn: &Arc, folder_manager: &Arc, + grid_manager: &Arc, user_session: &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()); - vec![user_module, folder_module, network_module] + let grid_module = mk_grid_module(grid_manager.clone()); + vec![user_module, folder_module, network_module, grid_module] } fn mk_user_module(user_session: Arc) -> Module { flowy_user::event_map::create(user_session) } -fn mk_folder_module(core: Arc) -> Module { - flowy_folder::event_map::create(core) +fn mk_folder_module(folder_manager: Arc) -> Module { + flowy_folder::event_map::create(folder_manager) } fn mk_network_module(ws_conn: Arc) -> Module { flowy_net::event_map::create(ws_conn) } + +fn mk_grid_module(grid_manager: Arc) -> Module { + flowy_grid::event_map::create(grid_manager) +} diff --git a/shared-lib/lib-ws/src/msg.rs b/shared-lib/lib-ws/src/msg.rs index 522491a8a6..51f0a76607 100644 --- a/shared-lib/lib-ws/src/msg.rs +++ b/shared-lib/lib-ws/src/msg.rs @@ -12,10 +12,12 @@ pub struct WebSocketRawMessage { pub data: Vec, } +// The lib-ws crate should not contain business logic.So WSChannel should be removed into another place. #[derive(ProtoBuf_Enum, Debug, Clone, Eq, PartialEq, Hash)] pub enum WSChannel { Document = 0, Folder = 1, + Grid = 2, } impl std::default::Default for WSChannel { @@ -29,6 +31,7 @@ impl ToString for WSChannel { match self { WSChannel::Document => "0".to_string(), WSChannel::Folder => "1".to_string(), + WSChannel::Grid => "2".to_string(), } } } diff --git a/shared-lib/lib-ws/src/protobuf/model/msg.rs b/shared-lib/lib-ws/src/protobuf/model/msg.rs index 0911d4e9b9..35537df3f0 100644 --- a/shared-lib/lib-ws/src/protobuf/model/msg.rs +++ b/shared-lib/lib-ws/src/protobuf/model/msg.rs @@ -217,6 +217,7 @@ impl ::protobuf::reflect::ProtobufValue for WebSocketRawMessage { pub enum WSChannel { Document = 0, Folder = 1, + Grid = 2, } impl ::protobuf::ProtobufEnum for WSChannel { @@ -228,6 +229,7 @@ impl ::protobuf::ProtobufEnum for WSChannel { match value { 0 => ::std::option::Option::Some(WSChannel::Document), 1 => ::std::option::Option::Some(WSChannel::Folder), + 2 => ::std::option::Option::Some(WSChannel::Grid), _ => ::std::option::Option::None } } @@ -236,6 +238,7 @@ impl ::protobuf::ProtobufEnum for WSChannel { static values: &'static [WSChannel] = &[ WSChannel::Document, WSChannel::Folder, + WSChannel::Grid, ]; values } @@ -266,8 +269,8 @@ impl ::protobuf::reflect::ProtobufValue for WSChannel { static file_descriptor_proto_data: &'static [u8] = b"\ \n\tmsg.proto\"O\n\x13WebSocketRawMessage\x12$\n\x07channel\x18\x01\x20\ \x01(\x0e2\n.WSChannelR\x07channel\x12\x12\n\x04data\x18\x02\x20\x01(\ - \x0cR\x04data*%\n\tWSChannel\x12\x0c\n\x08Document\x10\0\x12\n\n\x06Fold\ - er\x10\x01b\x06proto3\ + \x0cR\x04data*/\n\tWSChannel\x12\x0c\n\x08Document\x10\0\x12\n\n\x06Fold\ + er\x10\x01\x12\x08\n\x04Grid\x10\x02b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/lib-ws/src/protobuf/proto/msg.proto b/shared-lib/lib-ws/src/protobuf/proto/msg.proto index e5237ddef0..9306bd499b 100644 --- a/shared-lib/lib-ws/src/protobuf/proto/msg.proto +++ b/shared-lib/lib-ws/src/protobuf/proto/msg.proto @@ -7,4 +7,5 @@ message WebSocketRawMessage { enum WSChannel { Document = 0; Folder = 1; + Grid = 2; } From 8029f1035d40c400b29834e46e6a3129c27d6ecc Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 5 Mar 2022 10:59:44 +0800 Subject: [PATCH 11/17] chore: impl handler logic --- frontend/app_flowy/lib/plugin/plugin.dart | 4 +- .../presentation/plugins/doc/document.dart | 2 +- .../dart_event/flowy-grid/dart_event.dart | 17 --- .../flowy-folder-data-model/view.pbenum.dart | 2 + .../flowy-folder-data-model/view.pbjson.dart | 3 +- .../protobuf/flowy-grid/event_map.pbenum.dart | 10 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 11 +- frontend/rust-lib/Cargo.lock | 1 + frontend/rust-lib/flowy-block/src/manager.rs | 6 +- .../rust-lib/flowy-folder/src/controller.rs | 9 +- .../persistence/version_1/view_sql.rs | 4 + .../src/services/view/controller.rs | 26 ++--- .../tests/workspace/folder_test.rs | 4 +- frontend/rust-lib/flowy-grid/Cargo.toml | 2 +- .../rust-lib/flowy-grid/src/event_handler.rs | 44 ++++---- frontend/rust-lib/flowy-grid/src/event_map.rs | 12 +-- frontend/rust-lib/flowy-grid/src/manager.rs | 101 ++++++++++++++++-- .../src/protobuf/model/event_map.rs | 27 +++-- .../src/protobuf/proto/event_map.proto | 9 +- .../flowy-grid/src/services/grid_editor.rs | 71 ++++++------ .../rust-lib/flowy-grid/src/services/mod.rs | 2 +- .../flowy-net/src/local_server/server.rs | 4 +- .../src/client_document/default/mod.rs | 6 +- .../src/client_document/document_pad.rs | 4 +- .../src/client_grid/grid_pad.rs | 20 +++- .../src/entities/revision.rs | 12 +-- .../src/entities/view.rs | 2 + .../src/protobuf/model/view.rs | 9 +- .../src/protobuf/proto/view.proto | 1 + .../src/entities/grid.rs | 57 +++++++++- 30 files changed, 304 insertions(+), 178 deletions(-) diff --git a/frontend/app_flowy/lib/plugin/plugin.dart b/frontend/app_flowy/lib/plugin/plugin.dart index 5007e92e18..c9f7d2abd1 100644 --- a/frontend/app_flowy/lib/plugin/plugin.dart +++ b/frontend/app_flowy/lib/plugin/plugin.dart @@ -10,7 +10,7 @@ import 'package:flutter/widgets.dart'; export "./src/sandbox.dart"; enum DefaultPlugin { - quillEditor, + quill, blank, trash, grid, @@ -19,7 +19,7 @@ enum DefaultPlugin { extension FlowyDefaultPluginExt on DefaultPlugin { int type() { switch (this) { - case DefaultPlugin.quillEditor: + case DefaultPlugin.quill: return 0; case DefaultPlugin.blank: return 1; 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 72465dd54b..b5b368fd72 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart @@ -47,7 +47,7 @@ class DocumentPluginBuilder extends PluginBuilder { String get menuName => "Doc"; @override - PluginType get pluginType => DefaultPlugin.quillEditor.type(); + PluginType get pluginType => DefaultPlugin.quill.type(); @override ViewDataType get dataType => ViewDataType.RichText; 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 21e2804539..52a51cd026 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 @@ -1,23 +1,6 @@ /// Auto generate. Do not edit part of '../../dispatch.dart'; -class GridEventCreateGrid { - CreateGridPayload request; - GridEventCreateGrid(this.request); - - Future> send() { - final request = FFIRequest.create() - ..event = GridEvent.CreateGrid.toString() - ..payload = requestToBytes(this.request); - - return Dispatch.asyncRequest(request) - .then((bytesResult) => bytesResult.fold( - (okBytes) => left(Grid.fromBuffer(okBytes)), - (errBytes) => right(FlowyError.fromBuffer(errBytes)), - )); - } -} - class GridEventOpenGrid { GridId request; GridEventOpenGrid(this.request); 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 452830c084..400c1d579a 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 @@ -12,10 +12,12 @@ import 'package:protobuf/protobuf.dart' as $pb; class ViewDataType extends $pb.ProtobufEnum { static const ViewDataType RichText = ViewDataType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RichText'); static const ViewDataType PlainText = ViewDataType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PlainText'); + static const ViewDataType Grid = ViewDataType._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Grid'); static const $core.List values = [ RichText, PlainText, + Grid, ]; static final $core.Map<$core.int, ViewDataType> _byValue = $pb.ProtobufEnum.initByValue(values); 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 8c50bd08fc..8cb2913dfe 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 @@ -14,11 +14,12 @@ const ViewDataType$json = const { '2': const [ const {'1': 'RichText', '2': 0}, const {'1': 'PlainText', '2': 1}, + const {'1': 'Grid', '2': 2}, ], }; /// Descriptor for `ViewDataType`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List viewDataTypeDescriptor = $convert.base64Decode('CgxWaWV3RGF0YVR5cGUSDAoIUmljaFRleHQQABINCglQbGFpblRleHQQAQ=='); +final $typed_data.Uint8List viewDataTypeDescriptor = $convert.base64Decode('CgxWaWV3RGF0YVR5cGUSDAoIUmljaFRleHQQABINCglQbGFpblRleHQQARIICgRHcmlkEAI='); @$core.Deprecated('Use viewDescriptor instead') const View$json = const { '1': 'View', 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 2b523834c3..7877beefde 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 @@ -10,14 +10,12 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; class GridEvent extends $pb.ProtobufEnum { - static const GridEvent CreateGrid = GridEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateGrid'); - static const GridEvent OpenGrid = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'OpenGrid'); - static const GridEvent GetRows = GridEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRows'); - static const GridEvent GetFields = GridEvent._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields'); - static const GridEvent CreateRow = GridEvent._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); + static const GridEvent OpenGrid = GridEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'OpenGrid'); + 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 $core.List values = [ - CreateGrid, OpenGrid, GetRows, GetFields, 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 19412ddc1d..96b422a379 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 @@ -12,13 +12,12 @@ import 'dart:typed_data' as $typed_data; const GridEvent$json = const { '1': 'GridEvent', '2': const [ - const {'1': 'CreateGrid', '2': 0}, - const {'1': 'OpenGrid', '2': 1}, - const {'1': 'GetRows', '2': 2}, - const {'1': 'GetFields', '2': 3}, - const {'1': 'CreateRow', '2': 4}, + const {'1': 'OpenGrid', '2': 0}, + const {'1': 'GetRows', '2': 1}, + const {'1': 'GetFields', '2': 2}, + const {'1': 'CreateRow', '2': 3}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDgoKQ3JlYXRlR3JpZBAAEgwKCE9wZW5HcmlkEAESCwoHR2V0Um93cxACEg0KCUdldEZpZWxkcxADEg0KCUNyZWF0ZVJvdxAE'); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDAoIT3BlbkdyaWQQABILCgdHZXRSb3dzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAM='); diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index f5ae68cbda..1a8fce9353 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1071,6 +1071,7 @@ dependencies = [ "rusty-money", "strum", "strum_macros", + "tokio", "tracing", "uuid", ] diff --git a/frontend/rust-lib/flowy-block/src/manager.rs b/frontend/rust-lib/flowy-block/src/manager.rs index 6c9e23b4ed..d41edf045d 100644 --- a/frontend/rust-lib/flowy-block/src/manager.rs +++ b/frontend/rust-lib/flowy-block/src/manager.rs @@ -85,7 +85,7 @@ impl BlockManager { let doc_id = doc_id.as_ref().to_owned(); let db_pool = self.block_user.db_pool()?; // Maybe we could save the block to disk without creating the RevisionManager - let rev_manager = self.make_rev_manager(&doc_id, db_pool)?; + let rev_manager = self.make_block_rev_manager(&doc_id, db_pool)?; let _ = rev_manager.reset_object(revisions).await?; Ok(()) } @@ -125,7 +125,7 @@ impl BlockManager { ) -> Result, FlowyError> { let user = self.block_user.clone(); let token = self.block_user.token()?; - let rev_manager = self.make_rev_manager(block_id, pool.clone())?; + let rev_manager = self.make_block_rev_manager(block_id, pool.clone())?; let cloud_service = Arc::new(BlockRevisionCloudService { token, server: self.cloud_service.clone(), @@ -136,7 +136,7 @@ impl BlockManager { Ok(doc_editor) } - fn make_rev_manager(&self, doc_id: &str, pool: Arc) -> Result { + fn make_block_rev_manager(&self, doc_id: &str, pool: Arc) -> Result { let user_id = self.block_user.user_id()?; let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, doc_id, pool)); Ok(RevisionManager::new(&user_id, doc_id, rev_persistence)) diff --git a/frontend/rust-lib/flowy-folder/src/controller.rs b/frontend/rust-lib/flowy-folder/src/controller.rs index a01a26b7d5..528a602d57 100644 --- a/frontend/rust-lib/flowy-folder/src/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/controller.rs @@ -1,6 +1,6 @@ use bytes::Bytes; use chrono::Utc; -use flowy_collaboration::client_document::default::{initial_delta, initial_read_me}; +use flowy_collaboration::client_document::default::{initial_quill_delta, initial_quill_delta_string, initial_read_me}; use flowy_folder_data_model::user_default; use flowy_sync::RevisionWebSocket; use lazy_static::lazy_static; @@ -199,13 +199,10 @@ impl DefaultFolderBuilder { let view_data = if index == 0 { initial_read_me().to_delta_json() } else { - initial_delta().to_delta_json() + initial_quill_delta_string() }; view_controller.set_latest_view(view); - let delta_data = Bytes::from(view_data); - let repeated_revision: RepeatedRevision = - Revision::initial_revision(user_id, &view.id, delta_data).into(); - let _ = view_controller.create_view(&view.id, repeated_revision).await?; + let _ = view_controller.create_view(&view.id, Bytes::from(view_data)).await?; } } let folder = FolderPad::new(vec![workspace.clone()], vec![])?; 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 955bf44818..d87b761a7f 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 @@ -86,6 +86,7 @@ impl ViewTable { let data_type = match view.data_type { ViewDataType::RichText => SqlViewDataType::RichText, ViewDataType::PlainText => SqlViewDataType::PlainText, + ViewDataType::Grid => SqlViewDataType::Grid, }; ViewTable { @@ -108,6 +109,7 @@ impl std::convert::From for View { let data_type = match table.view_type { SqlViewDataType::RichText => ViewDataType::RichText, SqlViewDataType::PlainText => ViewDataType::PlainText, + SqlViewDataType::Grid => ViewDataType::Grid, }; View { @@ -179,6 +181,7 @@ impl ViewChangeset { pub enum SqlViewDataType { RichText = 0, PlainText = 1, + Grid = 2, } impl std::default::Default for SqlViewDataType { @@ -192,6 +195,7 @@ impl std::convert::From for SqlViewDataType { match value { 0 => SqlViewDataType::RichText, 1 => SqlViewDataType::PlainText, + 2 => SqlViewDataType::Grid, o => { log::error!("Unsupported view type {}, fallback to ViewType::Docs", o); SqlViewDataType::PlainText 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 32e4aa5136..57cdeba7d1 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -4,7 +4,7 @@ use flowy_collaboration::entities::{ revision::{RepeatedRevision, Revision}, }; -use flowy_collaboration::client_document::default::initial_delta_string; +use flowy_collaboration::client_document::default::initial_quill_delta_string; use futures::{FutureExt, StreamExt}; use std::{collections::HashSet, sync::Arc}; @@ -63,30 +63,24 @@ impl ViewController { #[tracing::instrument(level = "trace", skip(self, params), fields(name = %params.name), err)] pub(crate) async fn create_view_from_params(&self, params: CreateViewParams) -> Result { let view_data = if params.data.is_empty() { - initial_delta_string() + initial_quill_delta_string() } else { params.data.clone() }; - let delta_data = Bytes::from(view_data); - let user_id = self.user.user_id()?; - let repeated_revision: RepeatedRevision = - Revision::initial_revision(&user_id, ¶ms.view_id, delta_data).into(); - let _ = self.create_view(¶ms.view_id, repeated_revision).await?; + let _ = self.create_view(¶ms.view_id, Bytes::from(view_data)).await?; let view = self.create_view_on_server(params).await?; let _ = self.create_view_on_local(view.clone()).await?; Ok(view) } - #[tracing::instrument(level = "debug", skip(self, view_id, repeated_revision), err)] - pub(crate) async fn create_view( - &self, - view_id: &str, - repeated_revision: RepeatedRevision, - ) -> Result<(), FlowyError> { - if repeated_revision.is_empty() { + #[tracing::instrument(level = "debug", skip(self, view_id, delta_data), err)] + pub(crate) async fn create_view(&self, view_id: &str, delta_data: Bytes) -> Result<(), FlowyError> { + if delta_data.is_empty() { 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 _ = self.block_manager.create_block(view_id, repeated_revision).await?; Ok(()) } @@ -304,7 +298,7 @@ impl ViewController { fn listen_trash_can_event(&self) { let mut rx = self.trash_controller.subscribe(); let persistence = self.persistence.clone(); - let document_manager = self.block_manager.clone(); + let block_manager = self.block_manager.clone(); let trash_controller = self.trash_controller.clone(); let _ = tokio::spawn(async move { loop { @@ -318,7 +312,7 @@ impl ViewController { if let Some(event) = stream.next().await { handle_trash_event( persistence.clone(), - document_manager.clone(), + block_manager.clone(), trash_controller.clone(), event, ) 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 76b0aaf9c6..18a11d9a0b 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs @@ -1,5 +1,5 @@ use crate::script::{invalid_workspace_name_test_case, FolderScript::*, FolderTest}; -use flowy_collaboration::{client_document::default::initial_delta_string, entities::revision::RevisionState}; +use flowy_collaboration::{client_document::default::initial_quill_delta_string, entities::revision::RevisionState}; use flowy_folder::entities::workspace::CreateWorkspacePayload; use flowy_test::{event_builder::*, FlowySDKTest}; @@ -175,7 +175,7 @@ async fn open_document_view() { test.run_scripts(vec![OpenDocument]).await; let document_info = test.document_info.unwrap(); - assert_eq!(document_info.text, initial_delta_string()); + assert_eq!(document_info.text, initial_quill_delta_string()); } #[tokio::test] diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index 5c65fc5ebc..331dd03b9e 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -30,7 +30,7 @@ uuid = { version = "0.8", features = ["serde", "v4"] } bytes = { version = "1.0" } diesel = {version = "1.4.8", features = ["sqlite"]} dashmap = "4.0" - +tokio = {version = "1", features = ["sync"]} parking_lot = "0.11" diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 7d6e7f8e21..e1201408d4 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -3,53 +3,47 @@ use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ CreateGridPayload, Grid, GridId, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, }; -use lib_dispatch::prelude::{AppData, Data, DataResult}; +use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; -#[tracing::instrument(skip(data, controller), err)] -pub(crate) async fn create_grid_handler( - data: Data, - controller: AppData>, -) -> DataResult { - todo!() -} - -#[tracing::instrument(skip(data, controller), err)] +#[tracing::instrument(skip(data, manager), err)] pub(crate) async fn open_grid_handler( data: Data, - controller: AppData>, + manager: AppData>, ) -> DataResult { - let _params: GridId = data.into_inner(); - - todo!() + let grid_id: GridId = data.into_inner(); + let editor = manager.open_grid(grid_id).await?; + let grid = editor.grid_data().await; + data_result(grid) } -#[tracing::instrument(skip(data, controller), err)] +#[tracing::instrument(skip(data, manager), err)] pub(crate) async fn get_rows_handler( data: Data, - controller: AppData>, + manager: AppData>, ) -> DataResult { let row_orders: RepeatedRowOrder = data.into_inner(); - - todo!() + let repeated_row = manager.get_rows(row_orders).await; + data_result(repeated_row) } -#[tracing::instrument(skip(data, controller), err)] +#[tracing::instrument(skip(data, manager), err)] pub(crate) async fn get_fields_handler( data: Data, - controller: AppData>, + manager: AppData>, ) -> DataResult { let field_orders: RepeatedFieldOrder = data.into_inner(); - - todo!() + let repeated_field = manager.get_fields(field_orders).await; + data_result(repeated_field) } -#[tracing::instrument(skip(data, controller), err)] +#[tracing::instrument(skip(data, manager), err)] pub(crate) async fn create_row_handler( data: Data, - controller: AppData>, + manager: AppData>, ) -> Result<(), FlowyError> { let id: GridId = 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 787cd6336d..bd52c9f0f4 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -8,7 +8,6 @@ use strum_macros::Display; pub fn create(grid_manager: Arc) -> Module { let mut module = Module::new().name(env!("CARGO_PKG_NAME")).data(grid_manager); module = module - .event(GridEvent::CreateGrid, create_grid_handler) .event(GridEvent::OpenGrid, open_grid_handler) .event(GridEvent::GetRows, get_rows_handler) .event(GridEvent::GetFields, get_fields_handler) @@ -20,18 +19,15 @@ pub fn create(grid_manager: Arc) -> Module { #[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] #[event_err = "FlowyError"] pub enum GridEvent { - #[event(input = "CreateGridPayload", output = "Grid")] - CreateGrid = 0, - #[event(input = "GridId", output = "Grid")] - OpenGrid = 1, + OpenGrid = 0, #[event(input = "RepeatedRowOrder", output = "RepeatedRow")] - GetRows = 2, + GetRows = 1, #[event(input = "RepeatedFieldOrder", output = "RepeatedField")] - GetFields = 3, + GetFields = 2, #[event(input = "GridId")] - CreateRow = 4, + CreateRow = 3, } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index af4de88293..694ead2d55 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -1,8 +1,15 @@ use crate::services::grid_editor::ClientGridEditor; +use crate::services::kv_persistence::GridKVPersistence; use dashmap::DashMap; +use flowy_collaboration::client_grid::{make_grid_delta, make_grid_revisions}; +use flowy_collaboration::entities::revision::RepeatedRevision; use flowy_error::{FlowyError, FlowyResult}; +use flowy_grid_data_model::entities::{ + Field, FieldOrder, Grid, RawRow, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, RowOrder, +}; use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; use lib_sqlite::ConnectionPool; +use parking_lot::RwLock; use std::sync::Arc; pub trait GridUser: Send + Sync { @@ -15,27 +22,63 @@ pub struct GridManager { grid_editors: Arc, grid_user: Arc, rev_web_socket: Arc, + kv_persistence: Arc>>>, } impl GridManager { pub fn new(grid_user: Arc, rev_web_socket: Arc) -> Self { let grid_editors = Arc::new(GridEditors::new()); + + // kv_persistence will be initialized after first access. + // See get_kv_persistence function below + let kv_persistence = Arc::new(RwLock::new(None)); Self { grid_editors, grid_user, rev_web_socket, + kv_persistence, } } - #[tracing::instrument(level = "debug", skip(self, grid_id), fields(grid_id), err)] - pub async fn open_grid>(&self, grid_id: T) -> Result, FlowyError> { + #[tracing::instrument(level = "debug", skip_all, err)] + pub async fn create_grid>( + &self, + grid_id: T, + fields: Option>, + rows: Option>, + ) -> FlowyResult<()> { let grid_id = grid_id.as_ref(); - tracing::Span::current().record("grid_id", &grid_id); - self.get_grid_editor(grid_id).await + let user_id = self.grid_user.user_id()?; + let mut field_orders = vec![]; + let mut row_orders = vec![]; + if let Some(fields) = fields { + field_orders = fields.iter().map(|field| FieldOrder::from(field)).collect::>(); + } + if let Some(rows) = rows { + row_orders = rows.iter().map(|row| RowOrder::from(row)).collect::>(); + } + + let grid = Grid { + id: grid_id.to_owned(), + field_orders: field_orders.into(), + row_orders: row_orders.into(), + }; + let revisions = make_grid_revisions(&user_id, &grid); + let db_pool = self.grid_user.db_pool()?; + let rev_manager = self.make_grid_rev_manager(grid_id, db_pool)?; + let _ = rev_manager.reset_object(revisions).await?; + Ok(()) } - #[tracing::instrument(level = "trace", skip(self, grid_id), fields(grid_id), err)] - pub fn close_grid>(&self, grid_id: T) -> Result<(), FlowyError> { + #[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(); + tracing::Span::current().record("grid_id", &grid_id); + self.get_or_create_grid_editor(grid_id).await + } + + #[tracing::instrument(level = "trace", skip_all, fields(grid_id), err)] + pub fn close_grid>(&self, grid_id: T) -> FlowyResult<()> { let grid_id = grid_id.as_ref(); tracing::Span::current().record("grid_id", &grid_id); self.grid_editors.remove(grid_id); @@ -43,14 +86,29 @@ impl GridManager { } #[tracing::instrument(level = "debug", skip(self, grid_id), fields(doc_id), err)] - pub fn delete_grid>(&self, grid_id: T) -> Result<(), FlowyError> { + pub fn delete_grid>(&self, grid_id: T) -> FlowyResult<()> { let grid_id = grid_id.as_ref(); tracing::Span::current().record("grid_id", &grid_id); self.grid_editors.remove(grid_id); Ok(()) } - async fn get_grid_editor(&self, grid_id: &str) -> FlowyResult> { + pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> RepeatedRow { + todo!() + } + + pub async fn get_fields(&self, field_orders: RepeatedFieldOrder) -> RepeatedField { + todo!() + } + + pub fn get_grid_editor(&self, grid_id: &str) -> FlowyResult> { + match self.grid_editors.get(grid_id) { + None => Err(FlowyError::internal().context("Should call open_grid function first")), + Some(editor) => Ok(editor), + } + } + + async fn get_or_create_grid_editor(&self, grid_id: &str) -> FlowyResult> { match self.grid_editors.get(grid_id) { None => { let db_pool = self.grid_user.db_pool()?; @@ -65,12 +123,33 @@ impl GridManager { grid_id: &str, pool: Arc, ) -> Result, FlowyError> { - let token = self.grid_user.token()?; - let user_id = self.grid_user.user_id()?; - let grid_editor = ClientGridEditor::new(&user_id, grid_id, &token, pool, self.rev_web_socket.clone()).await?; + 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?; self.grid_editors.insert(grid_id, &grid_editor); Ok(grid_editor) } + + 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 rev_manager = RevisionManager::new(&user_id, grid_id, rev_persistence); + Ok(rev_manager) + } + + fn get_kv_persistence(&self) -> FlowyResult> { + let read_guard = self.kv_persistence.read(); + if read_guard.is_some() { + return Ok(read_guard.clone().unwrap()); + } + drop(read_guard); + + let pool = self.grid_user.db_pool()?; + let kv_persistence = Arc::new(GridKVPersistence::new(pool)); + *self.kv_persistence.write() = Some(kv_persistence.clone()); + Ok(kv_persistence) + } } pub struct GridEditors { 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 b2456ff055..ec00eaf71c 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 @@ -25,11 +25,10 @@ #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum GridEvent { - CreateGrid = 0, - OpenGrid = 1, - GetRows = 2, - GetFields = 3, - CreateRow = 4, + OpenGrid = 0, + GetRows = 1, + GetFields = 2, + CreateRow = 3, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -39,18 +38,16 @@ impl ::protobuf::ProtobufEnum for GridEvent { fn from_i32(value: i32) -> ::std::option::Option { match value { - 0 => ::std::option::Option::Some(GridEvent::CreateGrid), - 1 => ::std::option::Option::Some(GridEvent::OpenGrid), - 2 => ::std::option::Option::Some(GridEvent::GetRows), - 3 => ::std::option::Option::Some(GridEvent::GetFields), - 4 => ::std::option::Option::Some(GridEvent::CreateRow), + 0 => ::std::option::Option::Some(GridEvent::OpenGrid), + 1 => ::std::option::Option::Some(GridEvent::GetRows), + 2 => ::std::option::Option::Some(GridEvent::GetFields), + 3 => ::std::option::Option::Some(GridEvent::CreateRow), _ => ::std::option::Option::None } } fn values() -> &'static [Self] { static values: &'static [GridEvent] = &[ - GridEvent::CreateGrid, GridEvent::OpenGrid, GridEvent::GetRows, GridEvent::GetFields, @@ -72,7 +69,7 @@ impl ::std::marker::Copy for GridEvent { impl ::std::default::Default for GridEvent { fn default() -> Self { - GridEvent::CreateGrid + GridEvent::OpenGrid } } @@ -83,9 +80,9 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*T\n\tGridEvent\x12\x0e\n\nCreateGrid\x10\0\x12\x0c\ - \n\x08OpenGrid\x10\x01\x12\x0b\n\x07GetRows\x10\x02\x12\r\n\tGetFields\ - \x10\x03\x12\r\n\tCreateRow\x10\x04b\x06proto3\ + \n\x0fevent_map.proto*D\n\tGridEvent\x12\x0c\n\x08OpenGrid\x10\0\x12\x0b\ + \n\x07GetRows\x10\x01\x12\r\n\tGetFields\x10\x02\x12\r\n\tCreateRow\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/event_map.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto index 82819b6bd5..d0b33de419 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 @@ -1,9 +1,8 @@ syntax = "proto3"; enum GridEvent { - CreateGrid = 0; - OpenGrid = 1; - GetRows = 2; - GetFields = 3; - CreateRow = 4; + OpenGrid = 0; + GetRows = 1; + GetFields = 2; + CreateRow = 3; } 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 974c026069..4a60254ca0 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,60 +1,64 @@ +use crate::manager::GridUser; use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use flowy_collaboration::client_grid::{GridChange, GridPad}; 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, GridId, RawRow}; +use flowy_grid_data_model::entities::{Field, Grid, GridId, RawRow}; use flowy_sync::{ RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder, RevisionPersistence, RevisionWebSocket, RevisionWebSocketManager, }; use lib_infra::future::FutureResult; +use lib_infra::uuid; use lib_ot::core::PlainTextAttributes; use lib_sqlite::ConnectionPool; -use parking_lot::RwLock; use std::sync::Arc; +use tokio::sync::RwLock; pub struct ClientGridEditor { - user_id: String, grid_id: String, - grid: Arc>, + user: Arc, + grid_pad: Arc>, rev_manager: Arc, - kv: Arc, + kv_persistence: Arc, } impl ClientGridEditor { pub async fn new( - user_id: &str, grid_id: &str, - token: &str, - pool: Arc, - _web_socket: Arc, + user: Arc, + mut rev_manager: RevisionManager, + kv_persistence: Arc, ) -> FlowyResult> { - let rev_persistence = Arc::new(RevisionPersistence::new(user_id, grid_id, pool.clone())); - let mut rev_manager = RevisionManager::new(user_id, grid_id, rev_persistence); - let cloud = Arc::new(GridRevisionCloudService { - token: token.to_string(), - }); - let grid = Arc::new(RwLock::new( + let token = user.token()?; + let cloud = Arc::new(GridRevisionCloudService { token }); + let grid_pad = Arc::new(RwLock::new( rev_manager.load::(cloud).await?, )); let rev_manager = Arc::new(rev_manager); - let kv = Arc::new(GridKVPersistence::new(pool)); - - let user_id = user_id.to_owned(); - let grid_id = grid_id.to_owned(); Ok(Arc::new(Self { - user_id, - grid_id, - grid, + grid_id: grid_id.to_owned(), + user, + grid_pad, rev_manager, - kv, + kv_persistence, })) } - pub async fn create_row(&self, row: RawRow) -> FlowyResult<()> { + 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(), + }; + self.create_row(row).await?; + Ok(()) + } + + async fn create_row(&self, row: RawRow) -> FlowyResult<()> { let _ = self.modify(|grid| Ok(grid.create_row(&row)?)).await?; - let _ = self.kv.set(row)?; + let _ = self.kv_persistence.set(row)?; Ok(()) } @@ -66,7 +70,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.set(field)?; + let _ = self.kv_persistence.set(field)?; Ok(()) } @@ -76,11 +80,15 @@ impl ClientGridEditor { Ok(()) } + pub async fn grid_data(&self) -> Grid { + self.grid_pad.read().await.grid_data() + } + async fn modify(&self, f: F) -> FlowyResult<()> where - F: FnOnce(&mut GridPad) -> FlowyResult>, + F: for<'a> FnOnce(&'a mut GridPad) -> FlowyResult>, { - let mut write_guard = self.grid.write(); + let mut write_guard = self.grid_pad.write().await; match f(&mut *write_guard)? { None => {} Some(change) => { @@ -92,6 +100,7 @@ impl ClientGridEditor { async fn apply_change(&self, change: GridChange) -> FlowyResult<()> { 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 revision = Revision::new( @@ -99,7 +108,7 @@ impl ClientGridEditor { base_rev_id, rev_id, delta_data, - &self.user_id, + &user_id, md5, ); let _ = self @@ -114,8 +123,8 @@ struct GridPadBuilder(); impl RevisionObjectBuilder for GridPadBuilder { type Output = GridPad; - fn build_object(_object_id: &str, revisions: Vec) -> FlowyResult { - let pad = GridPad::from_revisions(revisions)?; + fn build_object(object_id: &str, revisions: Vec) -> FlowyResult { + let pad = GridPad::from_revisions(object_id, revisions)?; Ok(pad) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index 0d9cae4f1c..f62472a0e8 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -3,6 +3,6 @@ mod util; pub mod cell_data; pub mod grid_editor; -mod kv_persistence; +pub mod kv_persistence; pub use stringify::*; 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 a9149720fb..3bfa30e06a 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/server.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/server.rs @@ -2,7 +2,7 @@ use crate::local_server::persistence::LocalDocumentCloudPersistence; use async_stream::stream; use bytes::Bytes; use flowy_collaboration::{ - client_document::default::initial_delta_string, + client_document::default::initial_quill_delta_string, entities::{ document_info::{BlockId, BlockInfo, CreateBlockParams, ResetBlockParams}, ws_data::{ClientRevisionWSData, ClientRevisionWSDataType}, @@ -420,7 +420,7 @@ impl BlockCloudService for LocalServer { fn read_block(&self, _token: &str, params: BlockId) -> FutureResult, FlowyError> { let doc = BlockInfo { block_id: params.value, - text: initial_delta_string(), + text: initial_quill_delta_string(), rev_id: 0, base_rev_id: 0, }; 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 35f674e41d..0466093bda 100644 --- a/shared-lib/flowy-collaboration/src/client_document/default/mod.rs +++ b/shared-lib/flowy-collaboration/src/client_document/default/mod.rs @@ -1,13 +1,13 @@ use lib_ot::{core::DeltaBuilder, rich_text::RichTextDelta}; #[inline] -pub fn initial_delta() -> RichTextDelta { +pub fn initial_quill_delta() -> RichTextDelta { DeltaBuilder::new().insert("\n").build() } #[inline] -pub fn initial_delta_string() -> String { - initial_delta().to_delta_json() +pub fn initial_quill_delta_string() -> String { + initial_quill_delta().to_delta_json() } #[inline] 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 99a86769ce..9f3bbe434b 100644 --- a/shared-lib/flowy-collaboration/src/client_document/document_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_document/document_pad.rs @@ -1,6 +1,6 @@ use crate::{ client_document::{ - default::initial_delta, + default::initial_quill_delta, history::{History, UndoResult}, view::{ViewExtensions, RECORD_THRESHOLD}, }, @@ -26,7 +26,7 @@ impl InitialDocumentText for PlainDoc { pub struct NewlineDoc(); impl InitialDocumentText for NewlineDoc { fn initial_delta() -> RichTextDelta { - initial_delta() + initial_quill_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 0d6eab93f2..4cc10614d7 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -1,4 +1,4 @@ -use crate::entities::revision::{md5, Revision}; +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::{CellChangeset, Field, FieldOrder, Grid, RawRow, RowOrder}; @@ -26,7 +26,7 @@ impl GridPad { }) } - pub fn from_revisions(revisions: Vec) -> CollaborateResult { + pub fn from_revisions(_grid_id: &str, revisions: Vec) -> CollaborateResult { let folder_delta: GridDelta = make_delta_from_revisions::(revisions)?; Self::from_delta(folder_delta) } @@ -81,6 +81,11 @@ impl GridPad { md5(&self.delta.to_bytes()) } + pub fn grid_data(&self) -> Grid { + let grid_ref: &Grid = &self.grid; + grid_ref.clone() + } + pub fn modify_grid(&mut self, f: F) -> CollaborateResult> where F: FnOnce(&mut Grid) -> CollaborateResult>, @@ -115,11 +120,18 @@ pub struct GridChange { pub md5: String, } -pub fn default_grid_delta(grid: &Grid) -> GridDelta { +pub fn make_grid_delta(grid: &Grid) -> GridDelta { let json = serde_json::to_string(&grid).unwrap(); PlainTextDeltaBuilder::new().insert(&json).build() } +pub fn make_grid_revisions(user_id: &str, grid: &Grid) -> RepeatedRevision { + let delta = make_grid_delta(grid); + let bytes = delta.to_bytes(); + let revision = Revision::initial_revision(user_id, &grid.id, bytes); + revision.into() +} + impl std::default::Default for GridPad { fn default() -> Self { let grid = Grid { @@ -127,7 +139,7 @@ impl std::default::Default for GridPad { field_orders: Default::default(), row_orders: Default::default(), }; - let delta = default_grid_delta(&grid); + let delta = make_grid_delta(&grid); GridPad { grid: Arc::new(grid), delta, diff --git a/shared-lib/flowy-collaboration/src/entities/revision.rs b/shared-lib/flowy-collaboration/src/entities/revision.rs index c85ba937fb..48853fa9ed 100644 --- a/shared-lib/flowy-collaboration/src/entities/revision.rs +++ b/shared-lib/flowy-collaboration/src/entities/revision.rs @@ -82,12 +82,6 @@ impl Revision { } } -impl std::convert::From for RepeatedRevision { - fn from(revision: Revision) -> Self { - RepeatedRevision { items: vec![revision] } - } -} - impl std::fmt::Debug for Revision { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { let _ = f.write_fmt(format_args!("object_id {}, ", self.object_id))?; @@ -125,6 +119,12 @@ impl std::ops::DerefMut for RepeatedRevision { } } +impl std::convert::From for RepeatedRevision { + fn from(revision: Revision) -> Self { + Self { items: vec![revision] } + } +} + impl RepeatedRevision { pub fn new(mut items: Vec) -> Self { items.sort_by(|a, b| a.rev_id.cmp(&b.rev_id)); 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 a16a384be1..53a6bd8caa 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/view.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/view.rs @@ -85,6 +85,7 @@ impl std::convert::From for Trash { pub enum ViewDataType { RichText = 0, PlainText = 1, + Grid = 2, } impl std::default::Default for ViewDataType { @@ -98,6 +99,7 @@ impl std::convert::From for ViewDataType { match val { 0 => ViewDataType::RichText, 1 => ViewDataType::PlainText, + 2 => ViewDataType::Grid, _ => { log::error!("Invalid view type: {}", val); ViewDataType::PlainText 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 0e1e3a7279..ddf9020243 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 @@ -2823,6 +2823,7 @@ impl ::protobuf::reflect::ProtobufValue for UpdateViewParams { pub enum ViewDataType { RichText = 0, PlainText = 1, + Grid = 2, } impl ::protobuf::ProtobufEnum for ViewDataType { @@ -2834,6 +2835,7 @@ impl ::protobuf::ProtobufEnum for ViewDataType { match value { 0 => ::std::option::Option::Some(ViewDataType::RichText), 1 => ::std::option::Option::Some(ViewDataType::PlainText), + 2 => ::std::option::Option::Some(ViewDataType::Grid), _ => ::std::option::Option::None } } @@ -2842,6 +2844,7 @@ impl ::protobuf::ProtobufEnum for ViewDataType { static values: &'static [ViewDataType] = &[ ViewDataType::RichText, ViewDataType::PlainText, + ViewDataType::Grid, ]; values } @@ -2904,9 +2907,9 @@ 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\x0c\n\x08RichText\x10\0\x12\r\n\tPlainText\x10\x01b\x06pr\ - oto3\ + \x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail*5\n\x0cVi\ + ewDataType\x12\x0c\n\x08RichText\x10\0\x12\r\n\tPlainText\x10\x01\x12\ + \x08\n\x04Grid\x10\x02b\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 b938e004f4..af05749a14 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 @@ -58,4 +58,5 @@ message UpdateViewParams { enum ViewDataType { RichText = 0; PlainText = 1; + Grid = 2; } 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 92ca8006e7..6d070e6893 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -26,6 +26,15 @@ pub struct FieldOrder { 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)] pub struct RepeatedFieldOrder { #[pb(index = 1)] @@ -33,6 +42,12 @@ pub struct RepeatedFieldOrder { 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; @@ -76,6 +91,18 @@ 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 + } +} #[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)] pub enum FieldType { @@ -156,6 +183,16 @@ pub struct RowOrder { 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, + } + } +} + #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)] pub struct RepeatedRowOrder { #[pb(index = 1)] @@ -163,9 +200,14 @@ pub struct RepeatedRowOrder { 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 { &self.items } @@ -210,6 +252,19 @@ pub struct RepeatedRow { 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 + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct Row { #[pb(index = 1)] From 11ceb96f65126b313246d537c164ee06c3e009ee Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 5 Mar 2022 17:52:25 +0800 Subject: [PATCH 12/17] feat: return rows and fields --- .../workspace/application/grid/grid_bloc.dart | 4 +- .../application/grid/grid_service.dart | 20 +- .../dart_event/flowy-grid/dart_event.dart | 4 +- .../flowy-grid-data-model/grid.pb.dart | 136 ++++- .../flowy-grid-data-model/grid.pbjson.dart | 26 +- frontend/rust-lib/Cargo.lock | 1 + frontend/rust-lib/flowy-folder/build.rs | 2 + frontend/rust-lib/flowy-grid/Cargo.toml | 2 +- frontend/rust-lib/flowy-grid/build.rs | 2 + .../rust-lib/flowy-grid/src/event_handler.rs | 17 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 4 +- frontend/rust-lib/flowy-grid/src/manager.rs | 12 +- .../flowy-grid/src/services/cell_data.rs | 14 +- .../flowy-grid/src/services/grid_editor.rs | 97 +++- .../flowy-grid/src/services/kv_persistence.rs | 80 +-- .../rust-lib/flowy-grid/src/services/mod.rs | 4 +- .../flowy-grid/src/services/stringify.rs | 44 +- frontend/rust-lib/flowy-net/build.rs | 2 + frontend/rust-lib/flowy-user/build.rs | 2 + .../src/client_grid/grid_pad.rs | 6 +- .../src/entities/grid.rs | 61 +- .../src/protobuf/model/grid.rs | 520 ++++++++++++++++-- .../src/protobuf/proto/grid.proto | 10 +- 23 files changed, 915 insertions(+), 155 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 40b145b8a4..f858113fcc 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -56,7 +56,7 @@ class GridBloc extends Bloc { Future _loadFields(Emitter emit) async { if (_grid != null) { - final result = await service.getFields(fieldOrders: _grid!.fieldOrders); + final result = await service.getFields(gridId: _grid!.id, fieldOrders: _grid!.fieldOrders); result.fold( (fields) { _fields = fields.items; @@ -70,7 +70,7 @@ class GridBloc extends Bloc { Future _loadGridInfo(Emitter emit) async { if (_grid != null && _fields != null) { - final result = await service.getRows(rowOrders: _grid!.rowOrders); + 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!); 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 e725f7ac84..5f0cda7813 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -4,11 +4,6 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:dartz/dartz.dart'; class GridService { - Future> createGrid({required String name}) { - final payload = CreateGridPayload()..name = name; - return GridEventCreateGrid(payload).send(); - } - Future> openGrid({required String gridId}) { final payload = GridId(value: gridId); return GridEventOpenGrid(payload).send(); @@ -18,11 +13,18 @@ class GridService { return GridEventCreateRow(GridId(value: gridId)).send(); } - Future> getRows({required RepeatedRowOrder rowOrders}) { - return GridEventGetRows(rowOrders).send(); + Future> getRows({required String gridId, required RepeatedRowOrder rowOrders}) { + final payload = QueryRowPayload.create() + ..gridId = gridId + ..rowOrders = rowOrders; + return GridEventGetRows(payload).send(); } - Future> getFields({required RepeatedFieldOrder fieldOrders}) { - return GridEventGetFields(fieldOrders).send(); + Future> getFields( + {required String gridId, required RepeatedFieldOrder fieldOrders}) { + final payload = QueryFieldPayload.create() + ..gridId = gridId + ..fieldOrders = 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 52a51cd026..d7543eb486 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 @@ -19,7 +19,7 @@ class GridEventOpenGrid { } class GridEventGetRows { - RepeatedRowOrder request; + QueryRowPayload request; GridEventGetRows(this.request); Future> send() { @@ -36,7 +36,7 @@ class GridEventGetRows { } class GridEventGetFields { - RepeatedFieldOrder request; + QueryFieldPayload request; GridEventGetFields(this.request); Future> send() { 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 54139582fe..102be7fb09 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 @@ -619,7 +619,7 @@ class RawCell extends $pb.GeneratedMessage { ..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') + ..aOM(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: AnyData.create) ..hasRequiredFields = false ; @@ -628,7 +628,7 @@ class RawCell extends $pb.GeneratedMessage { $core.String? id, $core.String? rowId, $core.String? fieldId, - $core.String? data, + AnyData? data, }) { final _result = create(); if (id != null) { @@ -694,13 +694,15 @@ class RawCell extends $pb.GeneratedMessage { void clearFieldId() => clearField(3); @$pb.TagNumber(4) - $core.String get data => $_getSZ(3); + AnyData get data => $_getN(3); @$pb.TagNumber(4) - set data($core.String v) { $_setString(3, v); } + 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); } class RepeatedRow extends $pb.GeneratedMessage { @@ -1057,3 +1059,129 @@ class GridId extends $pb.GeneratedMessage { void clearValue() => clearField(1); } +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') + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', subBuilder: RepeatedFieldOrder.create) + ..hasRequiredFields = false + ; + + QueryFieldPayload._() : super(); + factory QueryFieldPayload({ + $core.String? gridId, + RepeatedFieldOrder? fieldOrders, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (fieldOrders != null) { + _result.fieldOrders = fieldOrders; + } + return _result; + } + factory QueryFieldPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory QueryFieldPayload.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') + QueryFieldPayload clone() => QueryFieldPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + QueryFieldPayload copyWith(void Function(QueryFieldPayload) updates) => super.copyWith((message) => updates(message as QueryFieldPayload)) as QueryFieldPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static QueryFieldPayload create() => QueryFieldPayload._(); + QueryFieldPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static QueryFieldPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static QueryFieldPayload? _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) + 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); +} + +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') + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', subBuilder: RepeatedRowOrder.create) + ..hasRequiredFields = false + ; + + QueryRowPayload._() : super(); + factory QueryRowPayload({ + $core.String? gridId, + RepeatedRowOrder? rowOrders, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (rowOrders != null) { + _result.rowOrders = rowOrders; + } + 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) + 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); +} + 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 23f606194a..9a97445271 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 @@ -145,12 +145,12 @@ const RawCell$json = 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'}, + const {'1': 'data', '3': 4, '4': 1, '5': 11, '6': '.AnyData', '10': 'data'}, ], }; /// Descriptor for `RawCell`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rawCellDescriptor = $convert.base64Decode('CgdSYXdDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhIKBGRhdGEYBCABKAlSBGRhdGE='); +final $typed_data.Uint8List rawCellDescriptor = $convert.base64Decode('CgdSYXdDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhwKBGRhdGEYBCABKAsyCC5BbnlEYXRhUgRkYXRh'); @$core.Deprecated('Use repeatedRowDescriptor instead') const RepeatedRow$json = const { '1': 'RepeatedRow', @@ -228,3 +228,25 @@ const GridId$json = const { /// Descriptor for `GridId`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridIdDescriptor = $convert.base64Decode('CgZHcmlkSWQSFAoFdmFsdWUYASABKAlSBXZhbHVl'); +@$core.Deprecated('Use queryFieldPayloadDescriptor instead') +const QueryFieldPayload$json = const { + '1': 'QueryFieldPayload', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'field_orders', '3': 2, '4': 1, '5': 11, '6': '.RepeatedFieldOrder', '10': 'fieldOrders'}, + ], +}; + +/// 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', + '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'}, + ], +}; + +/// Descriptor for `QueryRowPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List queryRowPayloadDescriptor = $convert.base64Decode('Cg9RdWVyeVJvd1BheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEjAKCnJvd19vcmRlcnMYAiABKAsyES5SZXBlYXRlZFJvd09yZGVyUglyb3dPcmRlcnM='); diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 1a8fce9353..1ce0e1b649 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1067,6 +1067,7 @@ dependencies = [ "lib-sqlite", "parking_lot", "protobuf", + "rayon", "rust_decimal", "rusty-money", "strum", diff --git a/frontend/rust-lib/flowy-folder/build.rs b/frontend/rust-lib/flowy-folder/build.rs index 4ab7b9e23d..4d4d3b13da 100644 --- a/frontend/rust-lib/flowy-folder/build.rs +++ b/frontend/rust-lib/flowy-folder/build.rs @@ -3,5 +3,7 @@ use lib_infra::code_gen; fn main() { let crate_name = env!("CARGO_PKG_NAME"); code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto"); + + #[cfg(feature = "dart")] code_gen::dart_event::gen(crate_name); } diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index 331dd03b9e..95a5899f5e 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -31,7 +31,7 @@ bytes = { version = "1.0" } diesel = {version = "1.4.8", features = ["sqlite"]} dashmap = "4.0" tokio = {version = "1", features = ["sync"]} - +rayon = "1.5" parking_lot = "0.11" [build-dependencies] diff --git a/frontend/rust-lib/flowy-grid/build.rs b/frontend/rust-lib/flowy-grid/build.rs index 4ab7b9e23d..4d4d3b13da 100644 --- a/frontend/rust-lib/flowy-grid/build.rs +++ b/frontend/rust-lib/flowy-grid/build.rs @@ -3,5 +3,7 @@ use lib_infra::code_gen; fn main() { let crate_name = env!("CARGO_PKG_NAME"); code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto"); + + #[cfg(feature = "dart")] code_gen::dart_event::gen(crate_name); } diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index e1201408d4..f8efe9f413 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::{ - CreateGridPayload, Grid, GridId, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, + CreateGridPayload, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedFieldOrder, + RepeatedRow, RepeatedRowOrder, }; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -19,21 +20,23 @@ pub(crate) async fn open_grid_handler( #[tracing::instrument(skip(data, manager), err)] pub(crate) async fn get_rows_handler( - data: Data, + data: Data, manager: AppData>, ) -> DataResult { - let row_orders: RepeatedRowOrder = data.into_inner(); - let repeated_row = manager.get_rows(row_orders).await; + 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?; data_result(repeated_row) } #[tracing::instrument(skip(data, manager), err)] pub(crate) async fn get_fields_handler( - data: Data, + data: Data, manager: AppData>, ) -> DataResult { - let field_orders: RepeatedFieldOrder = data.into_inner(); - let repeated_field = manager.get_fields(field_orders).await; + 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?; data_result(repeated_field) } diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index bd52c9f0f4..a5f6c7fe47 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -22,10 +22,10 @@ pub enum GridEvent { #[event(input = "GridId", output = "Grid")] OpenGrid = 0, - #[event(input = "RepeatedRowOrder", output = "RepeatedRow")] + #[event(input = "QueryRowPayload", output = "RepeatedRow")] GetRows = 1, - #[event(input = "RepeatedFieldOrder", output = "RepeatedField")] + #[event(input = "QueryFieldPayload", output = "RepeatedField")] GetFields = 2, #[event(input = "GridId")] diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 694ead2d55..ad521cfe59 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -1,11 +1,11 @@ use crate::services::grid_editor::ClientGridEditor; -use crate::services::kv_persistence::GridKVPersistence; +use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use dashmap::DashMap; use flowy_collaboration::client_grid::{make_grid_delta, make_grid_revisions}; use flowy_collaboration::entities::revision::RepeatedRevision; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Field, FieldOrder, Grid, RawRow, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, RowOrder, + Field, FieldOrder, Grid, RawRow, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, RowOrder, }; use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; use lib_sqlite::ConnectionPool; @@ -93,14 +93,6 @@ impl GridManager { Ok(()) } - pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> RepeatedRow { - todo!() - } - - pub async fn get_fields(&self, field_orders: RepeatedFieldOrder) -> RepeatedField { - todo!() - } - pub fn get_grid_editor(&self, grid_id: &str) -> FlowyResult> { match self.grid_editors.get(grid_id) { None => Err(FlowyError::internal().context("Should call open_grid function first")), diff --git a/frontend/rust-lib/flowy-grid/src/services/cell_data.rs b/frontend/rust-lib/flowy-grid/src/services/cell_data.rs index c44c320468..afa278fcd3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell_data.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell_data.rs @@ -17,7 +17,7 @@ use strum::IntoEnumIterator; use strum_macros::EnumIter; pub trait StringifyAnyData { - fn stringify_any_data(&self, data: &AnyData) -> String; + fn stringify_any_data(&self, data: AnyData) -> String; fn str_to_any_data(&self, s: &str) -> Result; } @@ -33,7 +33,7 @@ pub struct RichTextDescription { impl_any_data!(RichTextDescription, FieldType::RichText); impl StringifyAnyData for RichTextDescription { - fn stringify_any_data(&self, data: &AnyData) -> String { + fn stringify_any_data(&self, data: AnyData) -> String { data.to_string() } @@ -57,7 +57,7 @@ pub struct CheckboxDescription { impl_any_data!(CheckboxDescription, FieldType::Checkbox); impl StringifyAnyData for CheckboxDescription { - fn stringify_any_data(&self, data: &AnyData) -> String { + fn stringify_any_data(&self, data: AnyData) -> String { data.to_string() } @@ -133,7 +133,7 @@ impl DisplayCell for DateDescription { } impl StringifyAnyData for DateDescription { - fn stringify_any_data(&self, data: &AnyData) -> String { + fn stringify_any_data(&self, data: AnyData) -> String { match String::from_utf8(data.value.clone()) { Ok(s) => match s.parse::() { Ok(timestamp) => { @@ -257,7 +257,7 @@ pub struct SingleSelect { impl_any_data!(SingleSelect, FieldType::SingleSelect); impl StringifyAnyData for SingleSelect { - fn stringify_any_data(&self, data: &AnyData) -> String { + fn stringify_any_data(&self, data: AnyData) -> String { data.to_string() } @@ -283,7 +283,7 @@ pub struct MultiSelect { } impl_any_data!(MultiSelect, FieldType::MultiSelect); impl StringifyAnyData for MultiSelect { - fn stringify_any_data(&self, data: &AnyData) -> String { + fn stringify_any_data(&self, data: AnyData) -> String { data.to_string() } @@ -388,7 +388,7 @@ impl DisplayCell for NumberDescription { } impl StringifyAnyData for NumberDescription { - fn stringify_any_data(&self, data: &AnyData) -> String { + fn stringify_any_data(&self, data: AnyData) -> String { match String::from_utf8(data.value.clone()) { Ok(s) => match self.money_from_str(&s) { Some(money_str) => money_str, 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 4a60254ca0..4e692df48c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,10 +1,15 @@ use crate::manager::GridUser; use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; +use crate::services::stringify::stringify_deserialize; +use dashmap::mapref::one::Ref; +use dashmap::DashMap; use flowy_collaboration::client_grid::{GridChange, GridPad}; 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, GridId, RawRow}; +use flowy_grid_data_model::entities::{ + Cell, Field, Grid, GridId, RawCell, RawRow, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, +}; use flowy_sync::{ RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder, RevisionPersistence, RevisionWebSocket, RevisionWebSocketManager, @@ -13,6 +18,8 @@ use lib_infra::future::FutureResult; use lib_infra::uuid; use lib_ot::core::PlainTextAttributes; use lib_sqlite::ConnectionPool; +use rayon::iter::{IntoParallelIterator, ParallelIterator}; +use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; @@ -22,6 +29,8 @@ pub struct ClientGridEditor { grid_pad: Arc>, rev_manager: Arc, kv_persistence: Arc, + + field_map: DashMap, } impl ClientGridEditor { @@ -33,16 +42,19 @@ impl ClientGridEditor { ) -> FlowyResult> { let token = user.token()?; let cloud = Arc::new(GridRevisionCloudService { token }); - let grid_pad = Arc::new(RwLock::new( - 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_pad = Arc::new(RwLock::new(grid_pad)); + Ok(Arc::new(Self { grid_id: grid_id.to_owned(), user, grid_pad, rev_manager, kv_persistence, + field_map, })) } @@ -80,6 +92,65 @@ impl ClientGridEditor { 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 raw_rows: Vec = self.kv_persistence.batch_get(ids)?; + + let make_cell = |field_id: String, raw_cell: RawCell| { + 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; + } + + 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 = raw_rows + .into_par_iter() + .map(|raw_row| { + let mut row = Row::new(&raw_row.id); + row.cell_by_field_id = raw_row + .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 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()) + } + pub async fn grid_data(&self) -> Grid { self.grid_pad.read().await.grid_data() } @@ -119,6 +190,24 @@ impl ClientGridEditor { } } +async fn load_all_fields( + grid_pad: &GridPad, + kv_persistence: &Arc, +) -> FlowyResult> { + let field_ids = grid_pad + .field_orders() + .iter() + .map(|field_order| field_order.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) +} + struct GridPadBuilder(); impl RevisionObjectBuilder for GridPadBuilder { type Output = GridPad; 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 3538af16f9..db3bdfdd7b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs +++ b/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs @@ -6,7 +6,7 @@ use flowy_database::{ schema::{kv_table, kv_table::dsl}, }; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{Field, RawRow}; +use flowy_grid_data_model::entities::{Field, GridIdentifiable, RawRow}; use lib_infra::future::{BoxResultFuture, FutureResult}; use lib_sqlite::{ConnectionManager, ConnectionPool}; use std::sync::Arc; @@ -20,11 +20,12 @@ pub struct KeyValue { } pub trait KVTransaction { - fn get>(&self, key: &str) -> FlowyResult>; + fn get>(&self, key: &str) -> FlowyResult>; fn set>(&self, value: T) -> FlowyResult<()>; fn remove(&self, key: &str) -> FlowyResult<()>; - fn batch_get>(&self, keys: Vec) -> FlowyResult>; + fn batch_get>(&self, keys: Vec) + -> FlowyResult>; fn batch_set>(&self, values: Vec) -> FlowyResult<()>; fn batch_remove(&self, keys: Vec) -> FlowyResult<()>; } @@ -51,7 +52,7 @@ impl GridKVPersistence { } impl KVTransaction for GridKVPersistence { - fn get>(&self, key: &str) -> FlowyResult> { + fn get>(&self, key: &str) -> FlowyResult> { self.begin_transaction(|transaction| transaction.get(key)) } @@ -63,7 +64,10 @@ impl KVTransaction for GridKVPersistence { self.begin_transaction(|transaction| transaction.remove(key)) } - fn batch_get>(&self, keys: Vec) -> FlowyResult> { + fn batch_get>( + &self, + keys: Vec, + ) -> FlowyResult> { self.begin_transaction(|transaction| transaction.batch_get(keys)) } @@ -81,11 +85,11 @@ pub struct SqliteTransaction<'a> { } impl<'a> KVTransaction for SqliteTransaction<'a> { - fn get>(&self, key: &str) -> FlowyResult> { + fn get>(&self, key: &str) -> FlowyResult> { let item = dsl::kv_table .filter(kv_table::key.eq(key)) .first::(self.conn)?; - let value: T = item.try_into()?; + let value = T::try_from(Bytes::from(item.value)).unwrap(); Ok(Some(value)) } @@ -101,13 +105,16 @@ impl<'a> KVTransaction for SqliteTransaction<'a> { Ok(()) } - fn batch_get>(&self, keys: Vec) -> FlowyResult> { + fn batch_get>( + &self, + keys: Vec, + ) -> FlowyResult> { let items = dsl::kv_table .filter(kv_table::key.eq_any(&keys)) .load::(self.conn)?; let mut values = vec![]; for item in items { - let value: T = item.try_into()?; + let value = T::try_from(Bytes::from(item.value)).unwrap(); values.push(value); } Ok(values) @@ -128,40 +135,33 @@ impl<'a> KVTransaction for SqliteTransaction<'a> { } } -impl std::convert::From for KeyValue { - fn from(row: RawRow) -> Self { - let key = row.id.clone(); - let bytes: Bytes = row.try_into().unwrap(); +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; +// +// impl std::convert::TryInto for KeyValue { - 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::From for KeyValue { - fn from(field: Field) -> Self { - let key = field.id.clone(); - let bytes: Bytes = field.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); - Field::try_from(bytes) - .map_err(|e| FlowyError::internal().context(format!("Deserialize into field failed: {:?}", e))) - } -} +// 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))) +// } +// } diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index f62472a0e8..dc96f8af5b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -1,8 +1,6 @@ -mod stringify; mod util; pub mod cell_data; pub mod grid_editor; pub mod kv_persistence; - -pub use stringify::*; +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 index 299b7e8c96..3eab8f91a5 100644 --- a/frontend/rust-lib/flowy-grid/src/services/stringify.rs +++ b/frontend/rust-lib/flowy-grid/src/services/stringify.rs @@ -3,28 +3,26 @@ use crate::services::util::*; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; -pub trait AnyDataSerde { - fn 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), - } - } - - fn 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) +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-net/build.rs b/frontend/rust-lib/flowy-net/build.rs index 4ab7b9e23d..4d4d3b13da 100644 --- a/frontend/rust-lib/flowy-net/build.rs +++ b/frontend/rust-lib/flowy-net/build.rs @@ -3,5 +3,7 @@ use lib_infra::code_gen; fn main() { let crate_name = env!("CARGO_PKG_NAME"); code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto"); + + #[cfg(feature = "dart")] code_gen::dart_event::gen(crate_name); } diff --git a/frontend/rust-lib/flowy-user/build.rs b/frontend/rust-lib/flowy-user/build.rs index 4ab7b9e23d..4d4d3b13da 100644 --- a/frontend/rust-lib/flowy-user/build.rs +++ b/frontend/rust-lib/flowy-user/build.rs @@ -3,5 +3,7 @@ use lib_infra::code_gen; fn main() { let crate_name = env!("CARGO_PKG_NAME"); code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto"); + + #[cfg(feature = "dart")] code_gen::dart_event::gen(crate_name); } 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 4cc10614d7..4db744fc08 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::{CellChangeset, Field, FieldOrder, Grid, RawRow, RowOrder}; +use flowy_grid_data_model::entities::{CellChangeset, Field, FieldOrder, Grid, RawRow, RepeatedFieldOrder, RowOrder}; use lib_infra::uuid; use lib_ot::core::{FlowyStr, OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use std::sync::Arc; @@ -86,6 +86,10 @@ impl GridPad { grid_ref.clone() } + pub fn field_orders(&self) -> &RepeatedFieldOrder { + &self.grid.field_orders + } + pub fn modify_grid(&mut self, f: F) -> CollaborateResult> where F: FnOnce(&mut Grid) -> 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 6d070e6893..926ca1e750 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,10 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; use strum_macros::{Display, EnumIter, EnumString}; +pub trait GridIdentifiable { + fn id(&self) -> &str; +} + #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)] pub struct Grid { #[pb(index = 1)] @@ -62,7 +66,7 @@ impl std::ops::DerefMut for RepeatedFieldOrder { } } -#[derive(Debug, Default, ProtoBuf)] +#[derive(Debug, Clone, Default, ProtoBuf)] pub struct Field { #[pb(index = 1)] pub id: String, @@ -86,6 +90,12 @@ pub struct Field { pub type_options: AnyData, } +impl GridIdentifiable for Field { + fn id(&self) -> &str { + &self.id + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedField { #[pb(index = 1)] @@ -104,6 +114,12 @@ impl std::ops::DerefMut for RepeatedField { } } +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, @@ -140,7 +156,7 @@ impl FieldType { } } -#[derive(Debug, Default, ProtoBuf)] +#[derive(Debug, Clone, Default, ProtoBuf)] pub struct AnyData { #[pb(index = 1)] pub type_id: String, @@ -231,6 +247,12 @@ pub struct RawRow { pub cell_by_field_id: HashMap, } +impl GridIdentifiable for RawRow { + fn id(&self) -> &str { + &self.id + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct RawCell { #[pb(index = 1)] @@ -243,7 +265,7 @@ pub struct RawCell { pub field_id: String, #[pb(index = 4)] - pub data: String, + pub data: AnyData, } #[derive(Debug, Default, ProtoBuf)] @@ -265,6 +287,12 @@ impl std::ops::DerefMut for RepeatedRow { } } +impl std::convert::From> for RepeatedRow { + fn from(items: Vec) -> Self { + Self { items } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct Row { #[pb(index = 1)] @@ -274,6 +302,15 @@ pub struct Row { 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(), + } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct Cell { #[pb(index = 1)] @@ -318,3 +355,21 @@ impl AsRef for GridId { &self.value } } + +#[derive(ProtoBuf, Default)] +pub struct QueryFieldPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub field_orders: RepeatedFieldOrder, +} + +#[derive(ProtoBuf, Default)] +pub struct QueryRowPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub row_orders: RepeatedRowOrder, +} 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 1339098bea..f64dde24e6 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 @@ -2070,7 +2070,7 @@ pub struct RawCell { pub id: ::std::string::String, pub row_id: ::std::string::String, pub field_id: ::std::string::String, - pub data: ::std::string::String, + pub data: ::protobuf::SingularPtrField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -2165,35 +2165,47 @@ impl RawCell { ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) } - // string data = 4; + // .AnyData data = 4; - pub fn get_data(&self) -> &str { - &self.data + 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: ::std::string::String) { - self.data = v; + 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 ::std::string::String { - &mut self.data + 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) -> ::std::string::String { - ::std::mem::replace(&mut self.data, ::std::string::String::new()) + pub fn take_data(&mut self) -> AnyData { + self.data.take().unwrap_or_else(|| AnyData::new()) } } impl ::protobuf::Message for RawCell { fn is_initialized(&self) -> bool { + for v in &self.data { + if !v.is_initialized() { + return false; + } + }; true } @@ -2211,7 +2223,7 @@ impl ::protobuf::Message for RawCell { ::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_singular_message_into(wire_type, is, &mut self.data)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -2234,8 +2246,9 @@ impl ::protobuf::Message for RawCell { 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); + 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; } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -2252,8 +2265,10 @@ impl ::protobuf::Message for RawCell { if !self.field_id.is_empty() { os.write_string(3, &self.field_id)?; } - if !self.data.is_empty() { - os.write_string(4, &self.data)?; + 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)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -2308,7 +2323,7 @@ impl ::protobuf::Message for RawCell { |m: &RawCell| { &m.field_id }, |m: &mut RawCell| { &mut m.field_id }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "data", |m: &RawCell| { &m.data }, |m: &mut RawCell| { &mut m.data }, @@ -3557,6 +3572,438 @@ impl ::protobuf::reflect::ProtobufValue for GridId { } } +#[derive(PartialEq,Clone,Default)] +pub struct QueryFieldPayload { + // message fields + pub grid_id: ::std::string::String, + pub field_orders: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a QueryFieldPayload { + fn default() -> &'a QueryFieldPayload { + ::default_instance() + } +} + +impl QueryFieldPayload { + pub fn new() -> QueryFieldPayload { + ::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()) + } + + // .RepeatedFieldOrder field_orders = 2; + + + pub fn get_field_orders(&self) -> &RepeatedFieldOrder { + self.field_orders.as_ref().unwrap_or_else(|| ::default_instance()) + } + 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); + } + + // 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() + } + + // Take field + pub fn take_field_orders(&mut self) -> RepeatedFieldOrder { + self.field_orders.take().unwrap_or_else(|| RepeatedFieldOrder::new()) + } +} + +impl ::protobuf::Message for QueryFieldPayload { + fn is_initialized(&self) -> bool { + for v in &self.field_orders { + 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_singular_message_into(wire_type, is, &mut self.field_orders)?; + }, + _ => { + ::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 Some(ref v) = self.field_orders.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.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if let Some(ref v) = self.field_orders.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> QueryFieldPayload { + QueryFieldPayload::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: &QueryFieldPayload| { &m.grid_id }, + |m: &mut QueryFieldPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "field_orders", + |m: &QueryFieldPayload| { &m.field_orders }, + |m: &mut QueryFieldPayload| { &mut m.field_orders }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "QueryFieldPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static QueryFieldPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(QueryFieldPayload::new) + } +} + +impl ::protobuf::Clear for QueryFieldPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.field_orders.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for QueryFieldPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for QueryFieldPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct QueryRowPayload { + // message fields + pub grid_id: ::std::string::String, + pub row_orders: ::protobuf::SingularPtrField, + // 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()) + } + + // .RepeatedRowOrder row_orders = 2; + + + pub fn get_row_orders(&self) -> &RepeatedRowOrder { + self.row_orders.as_ref().unwrap_or_else(|| ::default_instance()) + } + 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); + } + + // 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() + } + + // Take field + pub fn take_row_orders(&mut self) -> RepeatedRowOrder { + self.row_orders.take().unwrap_or_else(|| RepeatedRowOrder::new()) + } +} + +impl ::protobuf::Message for QueryRowPayload { + fn is_initialized(&self) -> bool { + for v in &self.row_orders { + 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_singular_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())?; + }, + }; + } + ::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 Some(ref v) = self.row_orders.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.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if let Some(ref v) = self.row_orders.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> 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_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "row_orders", + |m: &QueryRowPayload| { &m.row_orders }, + |m: &mut QueryRowPayload| { &mut m.row_orders }, + )); + ::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.row_orders.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) + } +} + #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum FieldType { RichText = 0, @@ -3643,25 +4090,30 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \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\"_\n\x07RawCell\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ + 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\x12\n\x04data\x18\x04\x20\x01(\ - \tR\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(\t\ - R\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByF\ - ieldIdEntryR\rcellByFieldId\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03ke\ - y\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\x06row_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\x11CreateGridPayload\ - \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\tFieldType\x12\x0c\n\x08Ric\ - hText\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\ + 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\ "; 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 ee4210c061..79d6af77e1 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 @@ -45,7 +45,7 @@ message RawCell { string id = 1; string row_id = 2; string field_id = 3; - string data = 4; + AnyData data = 4; } message RepeatedRow { repeated Row items = 1; @@ -71,6 +71,14 @@ message CreateGridPayload { message GridId { string value = 1; } +message QueryFieldPayload { + string grid_id = 1; + RepeatedFieldOrder field_orders = 2; +} +message QueryRowPayload { + string grid_id = 1; + RepeatedRowOrder row_orders = 2; +} enum FieldType { RichText = 0; Number = 1; From 5c155a07bf4ee5f1ec97c51eaebf3bb314ef797c Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 5 Mar 2022 21:15:10 +0800 Subject: [PATCH 13/17] feat: move handles to flowy-block crate --- .../workspace/application/doc/share_bloc.dart | 2 +- .../application/doc/share_service.dart | 2 +- .../presentation/plugins/doc/document.dart | 2 +- .../packages/flowy_sdk/example/pubspec.lock | 6 +- .../windows/flutter/generated_plugins.cmake | 8 ++ .../dart_event/flowy-block/dart_event.dart | 37 ++++++++ .../flowy_sdk/lib/dispatch/dispatch.dart | 2 + .../entities.pb.dart} | 6 +- .../entities.pbenum.dart} | 2 +- .../entities.pbjson.dart} | 2 +- .../entities.pbserver.dart} | 4 +- .../protobuf/flowy-block/event_map.pb.dart | 11 +++ .../flowy-block/event_map.pbenum.dart | 26 ++++++ .../flowy-block/event_map.pbjson.dart | 21 +++++ .../flowy-block/event_map.pbserver.dart | 9 ++ .../lib/protobuf/flowy-block/protobuf.dart | 3 + .../flowy-folder-data-model/protobuf.dart | 1 - .../app_flowy/packages/flowy_sdk/pubspec.lock | 18 +++- frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- frontend/rust-lib/flowy-block/Cargo.toml | 6 +- frontend/rust-lib/flowy-block/Flowy.toml | 3 + frontend/rust-lib/flowy-block/build.rs | 9 ++ .../rust-lib/flowy-block/src/entities.rs | 0 .../rust-lib/flowy-block/src/event_handler.rs | 29 ++++++ .../rust-lib/flowy-block/src/event_map.rs | 26 ++++++ frontend/rust-lib/flowy-block/src/lib.rs | 4 + .../rust-lib/flowy-block/src/protobuf/mod.rs | 4 + .../src/protobuf/model/entities.rs | 14 +-- .../src/protobuf/model/event_map.rs | 91 +++++++++++++++++++ .../flowy-block/src/protobuf/model/mod.rs | 8 ++ .../src/protobuf/proto/entities.proto | 0 .../src/protobuf/proto/event_map.proto | 6 ++ .../flowy-block/tests/document/edit_script.rs | 2 +- .../rust-lib/flowy-folder/src/event_map.rs | 7 +- frontend/rust-lib/flowy-folder/src/lib.rs | 2 +- .../src/{controller.rs => manager.rs} | 4 +- .../src/services/folder_editor.rs | 2 +- .../src/services/persistence/migration.rs | 2 +- .../src/services/persistence/mod.rs | 2 +- .../src/services/view/controller.rs | 12 --- .../src/services/view/event_handler.rs | 19 ---- .../src/services/workspace/event_handler.rs | 2 +- frontend/rust-lib/flowy-sdk/Cargo.toml | 4 +- .../flowy-sdk/src/deps_resolve/folder_deps.rs | 13 +-- frontend/rust-lib/flowy-sdk/src/lib.rs | 22 ++--- frontend/rust-lib/flowy-sdk/src/module.rs | 8 +- .../src/entities/mod.rs | 1 - .../src/protobuf/model/mod.rs | 3 - 48 files changed, 370 insertions(+), 101 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-block/dart_event.dart rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-folder-data-model/share.pb.dart => flowy-block/entities.pb.dart} (98%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-folder-data-model/share.pbenum.dart => flowy-block/entities.pbenum.dart} (97%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-folder-data-model/share.pbjson.dart => flowy-block/entities.pbjson.dart} (98%) rename frontend/app_flowy/packages/flowy_sdk/lib/protobuf/{flowy-folder-data-model/share.pbserver.dart => flowy-block/entities.pbserver.dart} (85%) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbserver.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/protobuf.dart create mode 100644 frontend/rust-lib/flowy-block/Flowy.toml create mode 100644 frontend/rust-lib/flowy-block/build.rs rename shared-lib/flowy-folder-data-model/src/entities/share.rs => frontend/rust-lib/flowy-block/src/entities.rs (100%) create mode 100644 frontend/rust-lib/flowy-block/src/event_handler.rs create mode 100644 frontend/rust-lib/flowy-block/src/event_map.rs create mode 100644 frontend/rust-lib/flowy-block/src/protobuf/mod.rs rename shared-lib/flowy-folder-data-model/src/protobuf/model/share.rs => frontend/rust-lib/flowy-block/src/protobuf/model/entities.rs (96%) create mode 100644 frontend/rust-lib/flowy-block/src/protobuf/model/event_map.rs create mode 100644 frontend/rust-lib/flowy-block/src/protobuf/model/mod.rs rename shared-lib/flowy-folder-data-model/src/protobuf/proto/share.proto => frontend/rust-lib/flowy-block/src/protobuf/proto/entities.proto (100%) create mode 100644 frontend/rust-lib/flowy-block/src/protobuf/proto/event_map.proto rename frontend/rust-lib/flowy-folder/src/{controller.rs => manager.rs} (99%) diff --git a/frontend/app_flowy/lib/workspace/application/doc/share_bloc.dart b/frontend/app_flowy/lib/workspace/application/doc/share_bloc.dart index fe4b2e7f5c..4e4fe85e54 100644 --- a/frontend/app_flowy/lib/workspace/application/doc/share_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/doc/share_bloc.dart @@ -1,6 +1,6 @@ import 'package:app_flowy/workspace/application/doc/share_service.dart'; import 'package:app_flowy/workspace/application/markdown/delta_markdown.dart'; -import 'package:flowy_sdk/protobuf/flowy-folder-data-model/share.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-block/entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/doc/share_service.dart b/frontend/app_flowy/lib/workspace/application/doc/share_service.dart index eedc0913bb..26f27cca99 100644 --- a/frontend/app_flowy/lib/workspace/application/doc/share_service.dart +++ b/frontend/app_flowy/lib/workspace/application/doc/share_service.dart @@ -1,8 +1,8 @@ import 'dart:async'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; -import 'package:flowy_sdk/protobuf/flowy-folder-data-model/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-block/protobuf.dart'; class ShareService { Future> export(String docId, ExportType type) { 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 b5b368fd72..cf09edfc31 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart @@ -21,7 +21,7 @@ import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/widget/rounded_button.dart'; import 'package:flowy_sdk/log.dart'; -import 'package:flowy_sdk/protobuf/flowy-folder-data-model/share.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-block/entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flutter/material.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/example/pubspec.lock b/frontend/app_flowy/packages/flowy_sdk/example/pubspec.lock index 921bd4fb2b..4ad6cc1e98 100644 --- a/frontend/app_flowy/packages/flowy_sdk/example/pubspec.lock +++ b/frontend/app_flowy/packages/flowy_sdk/example/pubspec.lock @@ -7,7 +7,7 @@ packages: name: archive url: "https://pub.dartlang.org" source: hosted - version: "3.1.6" + version: "3.1.8" async: dependency: transitive description: @@ -200,7 +200,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.1" platform: dependency: transitive description: @@ -275,7 +275,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.8" + version: "0.4.9" typed_data: dependency: transitive description: diff --git a/frontend/app_flowy/packages/flowy_sdk/example/windows/flutter/generated_plugins.cmake b/frontend/app_flowy/packages/flowy_sdk/example/windows/flutter/generated_plugins.cmake index d71dbaabab..33c0fd0169 100644 --- a/frontend/app_flowy/packages/flowy_sdk/example/windows/flutter/generated_plugins.cmake +++ b/frontend/app_flowy/packages/flowy_sdk/example/windows/flutter/generated_plugins.cmake @@ -6,6 +6,9 @@ list(APPEND FLUTTER_PLUGIN_LIST flowy_sdk ) +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + set(PLUGIN_BUNDLED_LIBRARIES) foreach(plugin ${FLUTTER_PLUGIN_LIST}) @@ -14,3 +17,8 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST}) list(APPEND PLUGIN_BUNDLED_LIBRARIES $) list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-block/dart_event.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-block/dart_event.dart new file mode 100644 index 0000000000..f14e33f7cc --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-block/dart_event.dart @@ -0,0 +1,37 @@ + +/// Auto generate. Do not edit +part of '../../dispatch.dart'; +class BlockEventApplyDocDelta { + BlockDelta request; + BlockEventApplyDocDelta(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = BlockEvent.ApplyDocDelta.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (okBytes) => left(BlockDelta.fromBuffer(okBytes)), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + +class BlockEventExportDocument { + ExportPayload request; + BlockEventExportDocument(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = BlockEvent.ExportDocument.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (okBytes) => left(ExportData.fromBuffer(okBytes)), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + 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 b58175af0a..f26efb17e4 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart @@ -21,6 +21,7 @@ import 'package:flowy_sdk/ffi.dart' as ffi; 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'; @@ -33,6 +34,7 @@ part 'dart_event/flowy-folder/dart_event.dart'; part 'dart_event/flowy-net/dart_event.dart'; part 'dart_event/flowy-user/dart_event.dart'; part 'dart_event/flowy-grid/dart_event.dart'; +part 'dart_event/flowy-block/dart_event.dart'; enum FFIException { RequestIsEmpty, diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/share.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/entities.pb.dart similarity index 98% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/share.pb.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/entities.pb.dart index c90de870dd..bcd8d6051a 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/share.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/entities.pb.dart @@ -1,6 +1,6 @@ /// // Generated code. Do not modify. -// source: share.proto +// source: entities.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 @@ -9,9 +9,9 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; -import 'share.pbenum.dart'; +import 'entities.pbenum.dart'; -export 'share.pbenum.dart'; +export 'entities.pbenum.dart'; class ExportPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ExportPayload', createEmptyInstance: create) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/share.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/entities.pbenum.dart similarity index 97% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/share.pbenum.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/entities.pbenum.dart index aa1d037ab7..f5413e61f2 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/share.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/entities.pbenum.dart @@ -1,6 +1,6 @@ /// // Generated code. Do not modify. -// source: share.proto +// source: entities.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-folder-data-model/share.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/entities.pbjson.dart similarity index 98% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/share.pbjson.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/entities.pbjson.dart index 8224855b02..4935602b83 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/share.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/entities.pbjson.dart @@ -1,6 +1,6 @@ /// // Generated code. Do not modify. -// source: share.proto +// source: entities.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 diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/share.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/entities.pbserver.dart similarity index 85% rename from frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/share.pbserver.dart rename to frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/entities.pbserver.dart index 2fa95db4fe..88741cd6c2 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/share.pbserver.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/entities.pbserver.dart @@ -1,9 +1,9 @@ /// // Generated code. Do not modify. -// source: share.proto +// source: entities.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 'share.pb.dart'; +export 'entities.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pb.dart new file mode 100644 index 0000000000..5bfad20674 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pb.dart @@ -0,0 +1,11 @@ +/// +// Generated code. Do not modify. +// source: event_map.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 'event_map.pbenum.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbenum.dart new file mode 100644 index 0000000000..599e220c77 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbenum.dart @@ -0,0 +1,26 @@ +/// +// Generated code. Do not modify. +// source: event_map.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 BlockEvent extends $pb.ProtobufEnum { + static const BlockEvent ApplyDocDelta = BlockEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplyDocDelta'); + static const BlockEvent ExportDocument = BlockEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ExportDocument'); + + static const $core.List values = [ + ApplyDocDelta, + ExportDocument, + ]; + + static final $core.Map<$core.int, BlockEvent> _byValue = $pb.ProtobufEnum.initByValue(values); + static BlockEvent? valueOf($core.int value) => _byValue[value]; + + const BlockEvent._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbjson.dart new file mode 100644 index 0000000000..7ff062a62a --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbjson.dart @@ -0,0 +1,21 @@ +/// +// Generated code. Do not modify. +// source: event_map.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 blockEventDescriptor instead') +const BlockEvent$json = const { + '1': 'BlockEvent', + '2': const [ + const {'1': 'ApplyDocDelta', '2': 0}, + const {'1': 'ExportDocument', '2': 1}, + ], +}; + +/// Descriptor for `BlockEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List blockEventDescriptor = $convert.base64Decode('CgpCbG9ja0V2ZW50EhEKDUFwcGx5RG9jRGVsdGEQABISCg5FeHBvcnREb2N1bWVudBAB'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbserver.dart new file mode 100644 index 0000000000..e359d1146c --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: event_map.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 'event_map.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/protobuf.dart new file mode 100644 index 0000000000..a2db1d12ab --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/protobuf.dart @@ -0,0 +1,3 @@ +// Auto-generated, do not edit +export './entities.pb.dart'; +export './event_map.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/protobuf.dart index 4a0477e02c..4ca4fa1fd1 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/protobuf.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/protobuf.dart @@ -1,5 +1,4 @@ // Auto-generated, do not edit -export './share.pb.dart'; export './app.pb.dart'; export './view.pb.dart'; export './trash.pb.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/pubspec.lock b/frontend/app_flowy/packages/flowy_sdk/pubspec.lock index 5ece223a66..b1c06d8848 100644 --- a/frontend/app_flowy/packages/flowy_sdk/pubspec.lock +++ b/frontend/app_flowy/packages/flowy_sdk/pubspec.lock @@ -214,6 +214,13 @@ packages: description: flutter source: sdk version: "0.0.0" + freezed: + dependency: "direct dev" + description: + name: freezed + url: "https://pub.dartlang.org" + source: hosted + version: "0.14.1+2" freezed_annotation: dependency: "direct main" description: @@ -339,7 +346,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.1" pedantic: dependency: transitive description: @@ -394,6 +401,13 @@ packages: description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" source_span: dependency: transitive description: @@ -442,7 +456,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.8" + version: "0.4.9" timing: dependency: transitive description: 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/Cargo.toml b/frontend/rust-lib/flowy-block/Cargo.toml index 330e70a61a..3973ff2c6c 100644 --- a/frontend/rust-lib/flowy-block/Cargo.toml +++ b/frontend/rust-lib/flowy-block/Cargo.toml @@ -52,6 +52,10 @@ color-eyre = { version = "0.5", default-features = false } criterion = "0.3" rand = "0.7.3" +[build-dependencies] +lib-infra = { path = "../../../shared-lib/lib-infra", features = ["protobuf_file_gen", "proto_gen"] } + [features] http_server = [] -flowy_unit_test = ["lib-ot/flowy_unit_test", "flowy-sync/flowy_unit_test"] \ No newline at end of file +flowy_unit_test = ["lib-ot/flowy_unit_test", "flowy-sync/flowy_unit_test"] +dart = ["lib-infra/dart"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-block/Flowy.toml b/frontend/rust-lib/flowy-block/Flowy.toml new file mode 100644 index 0000000000..e6a5c4bd8f --- /dev/null +++ b/frontend/rust-lib/flowy-block/Flowy.toml @@ -0,0 +1,3 @@ + +proto_crates = ["src/event_map.rs", "src/entities.rs"] +event_files = ["src/event_map.rs"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-block/build.rs b/frontend/rust-lib/flowy-block/build.rs new file mode 100644 index 0000000000..4d4d3b13da --- /dev/null +++ b/frontend/rust-lib/flowy-block/build.rs @@ -0,0 +1,9 @@ +use lib_infra::code_gen; + +fn main() { + let crate_name = env!("CARGO_PKG_NAME"); + code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto"); + + #[cfg(feature = "dart")] + code_gen::dart_event::gen(crate_name); +} diff --git a/shared-lib/flowy-folder-data-model/src/entities/share.rs b/frontend/rust-lib/flowy-block/src/entities.rs similarity index 100% rename from shared-lib/flowy-folder-data-model/src/entities/share.rs rename to frontend/rust-lib/flowy-block/src/entities.rs diff --git a/frontend/rust-lib/flowy-block/src/event_handler.rs b/frontend/rust-lib/flowy-block/src/event_handler.rs new file mode 100644 index 0000000000..c074f8b277 --- /dev/null +++ b/frontend/rust-lib/flowy-block/src/event_handler.rs @@ -0,0 +1,29 @@ +use crate::entities::{ExportData, ExportParams, ExportPayload}; +use crate::BlockManager; +use flowy_collaboration::entities::document_info::BlockDelta; +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 apply_delta_handler( + data: Data, + manager: AppData>, +) -> DataResult { + let block_delta = manager.receive_local_delta(data.into_inner()).await?; + data_result(block_delta) +} + +#[tracing::instrument(skip(data, manager), err)] +pub(crate) async fn export_handler( + data: Data, + manager: AppData>, +) -> DataResult { + let params: ExportParams = data.into_inner().try_into()?; + let editor = manager.open_block(¶ms.view_id).await?; + let delta_json = editor.block_json().await?; + data_result(ExportData { + data: delta_json, + export_type: params.export_type, + }) +} diff --git a/frontend/rust-lib/flowy-block/src/event_map.rs b/frontend/rust-lib/flowy-block/src/event_map.rs new file mode 100644 index 0000000000..9997d7ca20 --- /dev/null +++ b/frontend/rust-lib/flowy-block/src/event_map.rs @@ -0,0 +1,26 @@ +use crate::event_handler::*; +use crate::BlockManager; +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 { + let mut module = Module::new().name(env!("CARGO_PKG_NAME")).data(block_manager); + + module = module + .event(BlockEvent::ApplyDocDelta, apply_delta_handler) + .event(BlockEvent::ExportDocument, export_handler); + + module +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] +#[event_err = "FlowyError"] +pub enum BlockEvent { + #[event(input = "BlockDelta", output = "BlockDelta")] + ApplyDocDelta = 0, + + #[event(input = "ExportPayload", output = "ExportData")] + ExportDocument = 1, +} diff --git a/frontend/rust-lib/flowy-block/src/lib.rs b/frontend/rust-lib/flowy-block/src/lib.rs index 0995bd2136..8f15fd7e31 100644 --- a/frontend/rust-lib/flowy-block/src/lib.rs +++ b/frontend/rust-lib/flowy-block/src/lib.rs @@ -1,8 +1,12 @@ pub mod block_editor; +mod entities; +mod event_handler; +pub mod event_map; pub mod manager; mod queue; mod web_socket; +pub mod protobuf; pub use manager::*; pub mod errors { pub use flowy_error::{internal_error, ErrorCode, FlowyError}; diff --git a/frontend/rust-lib/flowy-block/src/protobuf/mod.rs b/frontend/rust-lib/flowy-block/src/protobuf/mod.rs new file mode 100644 index 0000000000..da97aad28a --- /dev/null +++ b/frontend/rust-lib/flowy-block/src/protobuf/mod.rs @@ -0,0 +1,4 @@ +#![cfg_attr(rustfmt, rustfmt::skip)] +// Auto-generated, do not edit +mod model; +pub use model::*; \ No newline at end of file diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/model/share.rs b/frontend/rust-lib/flowy-block/src/protobuf/model/entities.rs similarity index 96% rename from shared-lib/flowy-folder-data-model/src/protobuf/model/share.rs rename to frontend/rust-lib/flowy-block/src/protobuf/model/entities.rs index a020837fb0..3846f9c76f 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/model/share.rs +++ b/frontend/rust-lib/flowy-block/src/protobuf/model/entities.rs @@ -17,7 +17,7 @@ #![allow(trivial_casts)] #![allow(unused_imports)] #![allow(unused_results)] -//! Generated file from `share.proto` +//! Generated file from `entities.proto` /// Generated files are compatible only with the same version /// of protobuf runtime. @@ -457,12 +457,12 @@ impl ::protobuf::reflect::ProtobufValue for ExportType { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0bshare.proto\"V\n\rExportPayload\x12\x17\n\x07view_id\x18\x01\x20\ - \x01(\tR\x06viewId\x12,\n\x0bexport_type\x18\x02\x20\x01(\x0e2\x0b.Expor\ - tTypeR\nexportType\"N\n\nExportData\x12\x12\n\x04data\x18\x01\x20\x01(\t\ - R\x04data\x12,\n\x0bexport_type\x18\x02\x20\x01(\x0e2\x0b.ExportTypeR\ne\ - xportType*.\n\nExportType\x12\x08\n\x04Text\x10\0\x12\x0c\n\x08Markdown\ - \x10\x01\x12\x08\n\x04Link\x10\x02b\x06proto3\ + \n\x0eentities.proto\"V\n\rExportPayload\x12\x17\n\x07view_id\x18\x01\ + \x20\x01(\tR\x06viewId\x12,\n\x0bexport_type\x18\x02\x20\x01(\x0e2\x0b.E\ + xportTypeR\nexportType\"N\n\nExportData\x12\x12\n\x04data\x18\x01\x20\ + \x01(\tR\x04data\x12,\n\x0bexport_type\x18\x02\x20\x01(\x0e2\x0b.ExportT\ + ypeR\nexportType*.\n\nExportType\x12\x08\n\x04Text\x10\0\x12\x0c\n\x08Ma\ + rkdown\x10\x01\x12\x08\n\x04Link\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-block/src/protobuf/model/event_map.rs b/frontend/rust-lib/flowy-block/src/protobuf/model/event_map.rs new file mode 100644 index 0000000000..3078739cf8 --- /dev/null +++ b/frontend/rust-lib/flowy-block/src/protobuf/model/event_map.rs @@ -0,0 +1,91 @@ +// 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 `event_map.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 BlockEvent { + ApplyDocDelta = 0, + ExportDocument = 1, +} + +impl ::protobuf::ProtobufEnum for BlockEvent { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(BlockEvent::ApplyDocDelta), + 1 => ::std::option::Option::Some(BlockEvent::ExportDocument), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [BlockEvent] = &[ + BlockEvent::ApplyDocDelta, + BlockEvent::ExportDocument, + ]; + 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::("BlockEvent", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for BlockEvent { +} + +impl ::std::default::Default for BlockEvent { + fn default() -> Self { + BlockEvent::ApplyDocDelta + } +} + +impl ::protobuf::reflect::ProtobufValue for BlockEvent { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x0fevent_map.proto*3\n\nBlockEvent\x12\x11\n\rApplyDocDelta\x10\0\x12\ + \x12\n\x0eExportDocument\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-block/src/protobuf/model/mod.rs b/frontend/rust-lib/flowy-block/src/protobuf/model/mod.rs new file mode 100644 index 0000000000..a8012019d4 --- /dev/null +++ b/frontend/rust-lib/flowy-block/src/protobuf/model/mod.rs @@ -0,0 +1,8 @@ +#![cfg_attr(rustfmt, rustfmt::skip)] +// Auto-generated, do not edit + +mod entities; +pub use entities::*; + +mod event_map; +pub use event_map::*; diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/proto/share.proto b/frontend/rust-lib/flowy-block/src/protobuf/proto/entities.proto similarity index 100% rename from shared-lib/flowy-folder-data-model/src/protobuf/proto/share.proto rename to frontend/rust-lib/flowy-block/src/protobuf/proto/entities.proto diff --git a/frontend/rust-lib/flowy-block/src/protobuf/proto/event_map.proto b/frontend/rust-lib/flowy-block/src/protobuf/proto/event_map.proto new file mode 100644 index 0000000000..adc99e6941 --- /dev/null +++ b/frontend/rust-lib/flowy-block/src/protobuf/proto/event_map.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +enum BlockEvent { + ApplyDocDelta = 0; + ExportDocument = 1; +} 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 441b4cd104..506509f0ae 100644 --- a/frontend/rust-lib/flowy-block/tests/document/edit_script.rs +++ b/frontend/rust-lib/flowy-block/tests/document/edit_script.rs @@ -27,7 +27,7 @@ impl EditorTest { let sdk = FlowySDKTest::default(); let _ = sdk.init_user().await; let test = ViewTest::new(&sdk).await; - let editor = sdk.document_manager.open_block(&test.view.id).await.unwrap(); + let editor = sdk.block_manager.open_block(&test.view.id).await.unwrap(); Self { sdk, editor } } diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index bd151f80b0..483de91cc3 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -1,5 +1,4 @@ use crate::{ - controller::FolderManager, entities::{ app::{App, AppId, CreateAppParams, UpdateAppParams}, trash::{RepeatedTrash, RepeatedTrashId}, @@ -7,6 +6,7 @@ use crate::{ workspace::{CreateWorkspaceParams, RepeatedWorkspace, UpdateWorkspaceParams, Workspace, WorkspaceId}, }, errors::FlowyError, + manager::FolderManager, services::{app::event_handler::*, trash::event_handler::*, view::event_handler::*, workspace::event_handler::*}, }; use flowy_database::DBConnection; @@ -64,8 +64,7 @@ pub fn create(folder: Arc) -> Module { .event(FolderEvent::DeleteView, delete_view_handler) .event(FolderEvent::DuplicateView, duplicate_view_handler) .event(FolderEvent::OpenView, open_view_handler) - .event(FolderEvent::CloseView, close_view_handler) - .event(FolderEvent::ApplyDocDelta, block_delta_handler); + .event(FolderEvent::CloseView, close_view_handler); module = module .event(FolderEvent::ReadTrash, read_trash_handler) @@ -74,8 +73,6 @@ pub fn create(folder: Arc) -> Module { .event(FolderEvent::RestoreAllTrash, restore_all_trash_handler) .event(FolderEvent::DeleteAllTrash, delete_all_trash_handler); - module = module.event(FolderEvent::ExportDocument, export_handler); - module } diff --git a/frontend/rust-lib/flowy-folder/src/lib.rs b/frontend/rust-lib/flowy-folder/src/lib.rs index 7ce085a8dd..0137664274 100644 --- a/frontend/rust-lib/flowy-folder/src/lib.rs +++ b/frontend/rust-lib/flowy-folder/src/lib.rs @@ -8,8 +8,8 @@ mod macros; #[macro_use] extern crate flowy_database; -pub mod controller; mod dart_notification; +pub mod manager; pub mod protobuf; mod util; diff --git a/frontend/rust-lib/flowy-folder/src/controller.rs b/frontend/rust-lib/flowy-folder/src/manager.rs similarity index 99% rename from frontend/rust-lib/flowy-folder/src/controller.rs rename to frontend/rust-lib/flowy-folder/src/manager.rs index 528a602d57..34dca68c4e 100644 --- a/frontend/rust-lib/flowy-folder/src/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -72,7 +72,7 @@ impl FolderManager { user: Arc, cloud_service: Arc, database: Arc, - document_manager: Arc, + block_manager: Arc, web_socket: Arc, ) -> Self { if let Ok(user_id) = user.user_id() { @@ -95,7 +95,7 @@ impl FolderManager { persistence.clone(), cloud_service.clone(), trash_controller.clone(), - document_manager, + block_manager, )); let app_controller = Arc::new(AppController::new( 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 6f032964e8..536eef4c9f 100644 --- a/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs +++ b/frontend/rust-lib/flowy-folder/src/services/folder_editor.rs @@ -4,7 +4,7 @@ use flowy_collaboration::{ entities::{revision::Revision, ws_data::ServerRevisionWSData}, }; -use crate::controller::FolderId; +use crate::manager::FolderId; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_sync::{ 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 258b8a1e55..3f499fc45f 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs @@ -1,4 +1,4 @@ -use crate::controller::FolderId; +use crate::manager::FolderId; use crate::{ event_map::WorkspaceDatabase, services::persistence::{AppTableSql, TrashTableSql, ViewTableSql, WorkspaceTableSql}, 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 77b6d2a6c4..fa473ea063 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs @@ -12,8 +12,8 @@ use tokio::sync::RwLock; pub use version_1::{app_sql::*, trash_sql::*, v1_impl::V1Transaction, view_sql::*, workspace_sql::*}; use crate::{ - controller::FolderId, event_map::WorkspaceDatabase, + manager::FolderId, services::{folder_editor::ClientFolderEditor, persistence::migration::FolderMigration}, }; use flowy_error::{FlowyError, FlowyResult}; 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 57cdeba7d1..e9c16cce16 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -23,8 +23,6 @@ use crate::{ }; use flowy_block::BlockManager; use flowy_database::kv::KV; -use flowy_folder_data_model::entities::share::{ExportData, ExportParams}; - use lib_infra::uuid; const LATEST_VIEW_ID: &str = "latest_view_id"; @@ -179,16 +177,6 @@ impl ViewController { Ok(()) } - #[tracing::instrument(level = "debug", skip(self, params), err)] - pub(crate) async fn export_view(&self, params: ExportParams) -> Result { - let editor = self.block_manager.open_block(¶ms.view_id).await?; - let delta_json = editor.block_json().await?; - Ok(ExportData { - data: delta_json, - export_type: params.export_type, - }) - } - // belong_to_id will be the app_id or view_id. #[tracing::instrument(level = "debug", skip(self), err)] pub(crate) async fn read_views_belong_to(&self, belong_to_id: &str) -> Result { diff --git a/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs b/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs index 002a2ac24f..bde232623d 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs @@ -9,7 +9,6 @@ use crate::{ services::{TrashController, ViewController}, }; use flowy_collaboration::entities::document_info::BlockDelta; -use flowy_folder_data_model::entities::share::{ExportData, ExportParams, ExportPayload}; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::{convert::TryInto, sync::Arc}; @@ -46,14 +45,6 @@ pub(crate) async fn update_view_handler( Ok(()) } -pub(crate) async fn block_delta_handler( - data: Data, - controller: AppData>, -) -> DataResult { - let block_delta = controller.receive_delta(data.into_inner()).await?; - data_result(block_delta) -} - pub(crate) async fn delete_view_handler( data: Data, view_controller: AppData>, @@ -102,13 +93,3 @@ pub(crate) async fn duplicate_view_handler( let _ = controller.duplicate_view(&view_id.value).await?; Ok(()) } - -#[tracing::instrument(skip(data, controller), err)] -pub(crate) async fn export_handler( - data: Data, - controller: AppData>, -) -> DataResult { - let params: ExportParams = data.into_inner().try_into()?; - let data = controller.export_view(params).await?; - data_result(data) -} diff --git a/frontend/rust-lib/flowy-folder/src/services/workspace/event_handler.rs b/frontend/rust-lib/flowy-folder/src/services/workspace/event_handler.rs index 5b464f25e4..02034750ee 100644 --- a/frontend/rust-lib/flowy-folder/src/services/workspace/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/services/workspace/event_handler.rs @@ -1,7 +1,7 @@ use crate::{ - controller::FolderManager, dart_notification::{send_dart_notification, FolderNotification}, errors::FlowyError, + manager::FolderManager, services::{get_current_workspace, read_local_workspace_apps, WorkspaceController}, }; use flowy_folder_data_model::entities::{ diff --git a/frontend/rust-lib/flowy-sdk/Cargo.toml b/frontend/rust-lib/flowy-sdk/Cargo.toml index 5f0de22ecd..c20b1cda62 100644 --- a/frontend/rust-lib/flowy-sdk/Cargo.toml +++ b/frontend/rust-lib/flowy-sdk/Cargo.toml @@ -13,7 +13,7 @@ flowy-net = { path = "../flowy-net" } flowy-folder = { path = "../flowy-folder", default-features = false } flowy-grid = { path = "../flowy-grid", default-features = false } flowy-database = { path = "../flowy-database" } -flowy-block = { path = "../flowy-block" } +flowy-block = { path = "../flowy-block", default-features = false } flowy-sync = { path = "../flowy-sync" } tracing = { version = "0.1" } @@ -40,4 +40,4 @@ futures-util = "0.3.15" [features] http_server = ["flowy-user/http_server", "flowy-folder/http_server", "flowy-block/http_server"] use_bunyan = ["lib-log/use_bunyan"] -dart = ["flowy-user/dart", "flowy-net/dart", "flowy-folder/dart", "flowy-collaboration/dart", "flowy-grid/dart"] +dart = ["flowy-user/dart", "flowy-net/dart", "flowy-folder/dart", "flowy-collaboration/dart", "flowy-grid/dart", "flowy-block/dart"] 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 3a791888ff..9e79c8c477 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 @@ -3,9 +3,9 @@ use flowy_block::BlockManager; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; use flowy_folder::{ - controller::FolderManager, errors::{internal_error, FlowyError}, event_map::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser}, + manager::FolderManager, }; use flowy_net::ClientServerConfiguration; use flowy_net::{ @@ -24,7 +24,7 @@ impl FolderDepsResolver { local_server: Option>, user_session: Arc, server_config: &ClientServerConfiguration, - document_manager: &Arc, + block_manager: &Arc, ws_conn: Arc, ) -> Arc { let user: Arc = Arc::new(WorkspaceUserImpl(user_session.clone())); @@ -36,14 +36,7 @@ impl FolderDepsResolver { }; let folder_manager = Arc::new( - FolderManager::new( - user.clone(), - cloud_service, - database, - document_manager.clone(), - web_socket, - ) - .await, + FolderManager::new(user.clone(), cloud_service, database, block_manager.clone(), web_socket).await, ); if let (Ok(user_id), Ok(token)) = (user.user_id(), user.token()) { diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index 5ea59b176d..2390601fce 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -4,7 +4,7 @@ pub use flowy_net::get_client_server_configuration; use crate::deps_resolve::*; use flowy_block::BlockManager; -use flowy_folder::{controller::FolderManager, errors::FlowyError}; +use flowy_folder::{errors::FlowyError, manager::FolderManager}; use flowy_grid::manager::GridManager; use flowy_net::ClientServerConfiguration; use flowy_net::{ @@ -87,7 +87,7 @@ pub struct FlowySDK { #[allow(dead_code)] config: FlowySDKConfig, pub user_session: Arc, - pub document_manager: Arc, + pub block_manager: Arc, pub folder_manager: Arc, pub grid_manager: Arc, pub dispatcher: Arc, @@ -102,9 +102,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, document_manager, folder_manager, local_server, grid_manager) = runtime.block_on(async { + let (user_session, 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 document_manager = BlockDepsResolver::resolve( + let block_manager = BlockDepsResolver::resolve( local_server.clone(), ws_conn.clone(), user_session.clone(), @@ -115,7 +115,7 @@ impl FlowySDK { local_server.clone(), user_session.clone(), &config.server_config, - &document_manager, + &block_manager, ws_conn.clone(), ) .await; @@ -126,17 +126,11 @@ impl FlowySDK { local_server.run(); } ws_conn.init().await; - ( - user_session, - document_manager, - folder_manager, - local_server, - grid_manager, - ) + (user_session, 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) + mk_modules(&ws_conn, &folder_manager, &grid_manager, &user_session, &block_manager) })); _start_listening(&dispatcher, &ws_conn, &user_session, &folder_manager); @@ -144,7 +138,7 @@ impl FlowySDK { Self { config, user_session, - document_manager, + 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 27d9c8dd8c..17179aa59c 100644 --- a/frontend/rust-lib/flowy-sdk/src/module.rs +++ b/frontend/rust-lib/flowy-sdk/src/module.rs @@ -1,4 +1,5 @@ -use flowy_folder::controller::FolderManager; +use flowy_block::BlockManager; +use flowy_folder::manager::FolderManager; use flowy_grid::manager::GridManager; use flowy_net::ws::connection::FlowyWebSocketConnect; use flowy_user::services::UserSession; @@ -10,6 +11,7 @@ pub fn mk_modules( folder_manager: &Arc, grid_manager: &Arc, user_session: &Arc, + block_manager: &Arc, ) -> Vec { let user_module = mk_user_module(user_session.clone()); let folder_module = mk_folder_module(folder_manager.clone()); @@ -33,3 +35,7 @@ fn mk_network_module(ws_conn: Arc) -> Module { 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) +} diff --git a/shared-lib/flowy-folder-data-model/src/entities/mod.rs b/shared-lib/flowy-folder-data-model/src/entities/mod.rs index a8388db4a3..3ee0f4b591 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/mod.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/mod.rs @@ -1,5 +1,4 @@ pub mod app; -pub mod share; pub mod trash; pub mod view; pub mod workspace; diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/model/mod.rs b/shared-lib/flowy-folder-data-model/src/protobuf/model/mod.rs index fae1a91d08..d12cb83589 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/model/mod.rs +++ b/shared-lib/flowy-folder-data-model/src/protobuf/model/mod.rs @@ -1,9 +1,6 @@ #![cfg_attr(rustfmt, rustfmt::skip)] // Auto-generated, do not edit -mod share; -pub use share::*; - mod app; pub use app::*; From 1b80934899e3679845546a4b7fb59c2111c367b9 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 5 Mar 2022 22:30:42 +0800 Subject: [PATCH 14/17] chore: impl view data processor --- .../flowy-collaboration/document_info.pb.dart | 16 ++-- .../document_info.pbjson.dart | 4 +- frontend/rust-lib/Cargo.lock | 2 + frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- .../rust-lib/flowy-block/src/block_editor.rs | 8 +- .../rust-lib/flowy-block/src/event_handler.rs | 2 +- frontend/rust-lib/flowy-block/src/manager.rs | 8 +- frontend/rust-lib/flowy-block/src/queue.rs | 8 +- .../flowy-block/tests/document/edit_script.rs | 2 +- .../tests/editor/attribute_test.rs | 2 +- .../rust-lib/flowy-block/tests/editor/mod.rs | 28 +++--- .../flowy-block/tests/editor/serde_test.rs | 6 +- frontend/rust-lib/flowy-folder/Cargo.toml | 1 + frontend/rust-lib/flowy-folder/src/manager.rs | 44 +++++---- .../src/services/view/controller.rs | 33 +++---- frontend/rust-lib/flowy-grid/src/manager.rs | 47 +++++----- .../flowy-grid/src/services/grid_editor.rs | 4 + frontend/rust-lib/flowy-sdk/Cargo.toml | 2 +- .../flowy-sdk/src/deps_resolve/folder_deps.rs | 90 ++++++++++++++++++- frontend/rust-lib/flowy-sdk/src/lib.rs | 7 +- .../src/client_document/default/mod.rs | 4 +- .../src/client_document/document_pad.rs | 8 +- .../src/client_grid/grid_pad.rs | 4 + .../src/entities/document_info.rs | 4 +- .../src/entities/revision.rs | 2 +- .../src/protobuf/model/document_info.rs | 46 +++++----- .../src/protobuf/proto/document_info.proto | 2 +- .../src/server_document/document_pad.rs | 2 +- .../src/server_folder/folder_pad.rs | 2 +- shared-lib/flowy-collaboration/src/util.rs | 4 +- .../src/entities/view.rs | 2 +- shared-lib/lib-ot/src/core/delta/delta.rs | 4 +- 32 files changed, 257 insertions(+), 145 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pb.dart index c97753ae9b..d2732dca6a 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pb.dart @@ -230,21 +230,21 @@ class ResetBlockParams extends $pb.GeneratedMessage { class BlockDelta extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlockDelta', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deltaJson') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deltaStr') ..hasRequiredFields = false ; BlockDelta._() : super(); factory BlockDelta({ $core.String? blockId, - $core.String? deltaJson, + $core.String? deltaStr, }) { final _result = create(); if (blockId != null) { _result.blockId = blockId; } - if (deltaJson != null) { - _result.deltaJson = deltaJson; + if (deltaStr != null) { + _result.deltaStr = deltaStr; } return _result; } @@ -279,13 +279,13 @@ class BlockDelta extends $pb.GeneratedMessage { void clearBlockId() => clearField(1); @$pb.TagNumber(2) - $core.String get deltaJson => $_getSZ(1); + $core.String get deltaStr => $_getSZ(1); @$pb.TagNumber(2) - set deltaJson($core.String v) { $_setString(1, v); } + set deltaStr($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasDeltaJson() => $_has(1); + $core.bool hasDeltaStr() => $_has(1); @$pb.TagNumber(2) - void clearDeltaJson() => clearField(2); + void clearDeltaStr() => clearField(2); } class NewDocUser extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbjson.dart index e1f5900185..4e3e1a0ecd 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbjson.dart @@ -48,12 +48,12 @@ const BlockDelta$json = const { '1': 'BlockDelta', '2': const [ const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'}, - const {'1': 'delta_json', '3': 2, '4': 1, '5': 9, '10': 'deltaJson'}, + const {'1': 'delta_str', '3': 2, '4': 1, '5': 9, '10': 'deltaStr'}, ], }; /// Descriptor for `BlockDelta`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List blockDeltaDescriptor = $convert.base64Decode('CgpCbG9ja0RlbHRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEh0KCmRlbHRhX2pzb24YAiABKAlSCWRlbHRhSnNvbg=='); +final $typed_data.Uint8List blockDeltaDescriptor = $convert.base64Decode('CgpCbG9ja0RlbHRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEhsKCWRlbHRhX3N0chgCIAEoCVIIZGVsdGFTdHI='); @$core.Deprecated('Use newDocUserDescriptor instead') const NewDocUser$json = const { '1': 'NewDocUser', diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 1ce0e1b649..4dd16b94db 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -986,6 +986,7 @@ dependencies = [ name = "flowy-folder" version = "0.1.0" dependencies = [ + "async-trait", "bincode", "bytes", "chrono", @@ -1133,6 +1134,7 @@ dependencies = [ name = "flowy-sdk" version = "0.1.0" dependencies = [ + "async-trait", "bincode", "bytes", "claim 0.5.0", 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-block/src/block_editor.rs b/frontend/rust-lib/flowy-block/src/block_editor.rs index 92f6217d2f..f8b0f87c6b 100644 --- a/frontend/rust-lib/flowy-block/src/block_editor.rs +++ b/frontend/rust-lib/flowy-block/src/block_editor.rs @@ -140,9 +140,9 @@ impl ClientBlockEditor { Ok(()) } - pub async fn block_json(&self) -> FlowyResult { + pub async fn delta_str(&self) -> FlowyResult { let (ret, rx) = oneshot::channel::>(); - let msg = EditorCommand::ReadBlockJson { ret }; + let msg = EditorCommand::ReadDeltaStr { ret }; let _ = self.edit_cmd_tx.send(msg).await; let json = rx.await.map_err(internal_error)??; Ok(json) @@ -196,7 +196,7 @@ fn spawn_edit_queue( impl ClientBlockEditor { pub async fn doc_json(&self) -> FlowyResult { let (ret, rx) = oneshot::channel::>(); - let msg = EditorCommand::ReadBlockJson { ret }; + let msg = EditorCommand::ReadDeltaStr { ret }; let _ = self.edit_cmd_tx.send(msg).await; let s = rx.await.map_err(internal_error)??; Ok(s) @@ -226,7 +226,7 @@ impl RevisionObjectBuilder for BlockInfoBuilder { Result::::Ok(BlockInfo { block_id: object_id.to_owned(), - text: delta.to_delta_json(), + text: delta.to_delta_str(), rev_id, base_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 c074f8b277..1dcf5d4333 100644 --- a/frontend/rust-lib/flowy-block/src/event_handler.rs +++ b/frontend/rust-lib/flowy-block/src/event_handler.rs @@ -21,7 +21,7 @@ pub(crate) async fn export_handler( ) -> DataResult { let params: ExportParams = data.into_inner().try_into()?; let editor = manager.open_block(¶ms.view_id).await?; - let delta_json = editor.block_json().await?; + let delta_json = editor.delta_str().await?; data_result(ExportData { data: delta_json, export_type: params.export_type, diff --git a/frontend/rust-lib/flowy-block/src/manager.rs b/frontend/rust-lib/flowy-block/src/manager.rs index d41edf045d..17ea23c7bb 100644 --- a/frontend/rust-lib/flowy-block/src/manager.rs +++ b/frontend/rust-lib/flowy-block/src/manager.rs @@ -63,7 +63,7 @@ impl BlockManager { } #[tracing::instrument(level = "debug", skip(self, doc_id), fields(doc_id), err)] - pub fn delete>(&self, doc_id: T) -> Result<(), FlowyError> { + 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); @@ -73,11 +73,11 @@ impl BlockManager { #[tracing::instrument(level = "debug", skip(self, delta), fields(doc_id = %delta.block_id), err)] pub async fn receive_local_delta(&self, delta: BlockDelta) -> Result { let editor = self.get_block_editor(&delta.block_id).await?; - let _ = editor.compose_local_delta(Bytes::from(delta.delta_json)).await?; - let document_json = editor.block_json().await?; + let _ = editor.compose_local_delta(Bytes::from(delta.delta_str)).await?; + let document_json = editor.delta_str().await?; Ok(BlockDelta { block_id: delta.block_id.clone(), - delta_json: document_json, + delta_str: document_json, }) } diff --git a/frontend/rust-lib/flowy-block/src/queue.rs b/frontend/rust-lib/flowy-block/src/queue.rs index 8ce74ce591..96e4e50f17 100644 --- a/frontend/rust-lib/flowy-block/src/queue.rs +++ b/frontend/rust-lib/flowy-block/src/queue.rs @@ -161,8 +161,8 @@ impl EditBlockQueue { let _ = self.save_local_delta(delta, md5).await?; let _ = ret.send(Ok(())); } - EditorCommand::ReadBlockJson { ret } => { - let data = self.document.read().await.to_json(); + EditorCommand::ReadDeltaStr { ret } => { + let data = self.document.read().await.delta_str(); let _ = ret.send(Ok(data)); } EditorCommand::ReadBlockDelta { ret } => { @@ -265,7 +265,7 @@ pub(crate) enum EditorCommand { Redo { ret: Ret<()>, }, - ReadBlockJson { + ReadDeltaStr { ret: Ret, }, #[allow(dead_code)] @@ -289,7 +289,7 @@ impl std::fmt::Debug for EditorCommand { EditorCommand::CanRedo { .. } => "CanRedo", EditorCommand::Undo { .. } => "Undo", EditorCommand::Redo { .. } => "Redo", - EditorCommand::ReadBlockJson { .. } => "ReadDocumentAsJson", + EditorCommand::ReadDeltaStr { .. } => "ReadDeltaStr", EditorCommand::ReadBlockDelta { .. } => "ReadDocumentAsDelta", }; f.write_str(s) 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 506509f0ae..0109302e96 100644 --- a/frontend/rust-lib/flowy-block/tests/document/edit_script.rs +++ b/frontend/rust-lib/flowy-block/tests/document/edit_script.rs @@ -77,7 +77,7 @@ impl EditorTest { let delta = self.editor.doc_delta().await.unwrap(); if expected_delta != delta { eprintln!("✅ expect: {}", expected,); - eprintln!("❌ receive: {}", delta.to_delta_json()); + eprintln!("❌ receive: {}", delta.to_delta_str()); } assert_eq!(expected_delta, delta); } 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 261ce60b6c..fb91e8125c 100644 --- a/frontend/rust-lib/flowy-block/tests/editor/attribute_test.rs +++ b/frontend/rust-lib/flowy-block/tests/editor/attribute_test.rs @@ -774,7 +774,7 @@ fn delta_compose() { delta = delta.compose(&d).unwrap(); } assert_eq!( - delta.to_delta_json(), + delta.to_delta_str(), r#"[{"insert":"a"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"\n"}]"# ); diff --git a/frontend/rust-lib/flowy-block/tests/editor/mod.rs b/frontend/rust-lib/flowy-block/tests/editor/mod.rs index 151652262f..64812b8d82 100644 --- a/frontend/rust-lib/flowy-block/tests/editor/mod.rs +++ b/frontend/rust-lib/flowy-block/tests/editor/mod.rs @@ -108,20 +108,20 @@ impl TestBuilder { TestOp::Insert(delta_i, s, index) => { let document = &mut self.documents[*delta_i]; let delta = document.insert(*index, s).unwrap(); - tracing::debug!("Insert delta: {}", delta.to_delta_json()); + tracing::debug!("Insert delta: {}", delta.to_delta_str()); self.deltas.insert(*delta_i, Some(delta)); } TestOp::Delete(delta_i, iv) => { let document = &mut self.documents[*delta_i]; let delta = document.replace(*iv, "").unwrap(); - tracing::trace!("Delete delta: {}", delta.to_delta_json()); + tracing::trace!("Delete delta: {}", delta.to_delta_str()); self.deltas.insert(*delta_i, Some(delta)); } TestOp::Replace(delta_i, iv, s) => { let document = &mut self.documents[*delta_i]; let delta = document.replace(*iv, s).unwrap(); - tracing::trace!("Replace delta: {}", delta.to_delta_json()); + tracing::trace!("Replace delta: {}", delta.to_delta_str()); self.deltas.insert(*delta_i, Some(delta)); } TestOp::InsertBold(delta_i, s, iv) => { @@ -133,7 +133,7 @@ impl TestBuilder { let document = &mut self.documents[*delta_i]; let attribute = RichTextAttribute::Bold(*enable); let delta = document.format(*iv, attribute).unwrap(); - tracing::trace!("Bold delta: {}", delta.to_delta_json()); + tracing::trace!("Bold delta: {}", delta.to_delta_str()); self.deltas.insert(*delta_i, Some(delta)); } TestOp::Italic(delta_i, iv, enable) => { @@ -143,28 +143,28 @@ impl TestBuilder { false => RichTextAttribute::Italic(false), }; let delta = document.format(*iv, attribute).unwrap(); - tracing::trace!("Italic delta: {}", delta.to_delta_json()); + tracing::trace!("Italic delta: {}", delta.to_delta_str()); self.deltas.insert(*delta_i, Some(delta)); } TestOp::Header(delta_i, iv, level) => { let document = &mut self.documents[*delta_i]; let attribute = RichTextAttribute::Header(*level); let delta = document.format(*iv, attribute).unwrap(); - tracing::trace!("Header delta: {}", delta.to_delta_json()); + tracing::trace!("Header delta: {}", delta.to_delta_str()); self.deltas.insert(*delta_i, Some(delta)); } TestOp::Link(delta_i, iv, link) => { let document = &mut self.documents[*delta_i]; let attribute = RichTextAttribute::Link(link.to_owned()); let delta = document.format(*iv, attribute).unwrap(); - tracing::trace!("Link delta: {}", delta.to_delta_json()); + tracing::trace!("Link delta: {}", delta.to_delta_str()); self.deltas.insert(*delta_i, Some(delta)); } TestOp::Bullet(delta_i, iv, enable) => { let document = &mut self.documents[*delta_i]; let attribute = RichTextAttribute::Bullet(*enable); let delta = document.format(*iv, attribute).unwrap(); - tracing::debug!("Bullet delta: {}", delta.to_delta_json()); + tracing::debug!("Bullet delta: {}", delta.to_delta_str()); self.deltas.insert(*delta_i, Some(delta)); } @@ -194,15 +194,15 @@ impl TestBuilder { let delta_a = &self.documents[*delta_a_i].delta(); let delta_b = &self.documents[*delta_b_i].delta(); tracing::debug!("Invert: "); - tracing::debug!("a: {}", delta_a.to_delta_json()); - tracing::debug!("b: {}", delta_b.to_delta_json()); + tracing::debug!("a: {}", delta_a.to_delta_str()); + tracing::debug!("b: {}", delta_b.to_delta_str()); let (_, b_prime) = delta_a.transform(delta_b).unwrap(); let undo = b_prime.invert(delta_a); let new_delta = delta_a.compose(&b_prime).unwrap(); - tracing::debug!("new delta: {}", new_delta.to_delta_json()); - tracing::debug!("undo delta: {}", undo.to_delta_json()); + tracing::debug!("new delta: {}", new_delta.to_delta_str()); + tracing::debug!("undo delta: {}", undo.to_delta_str()); let new_delta_after_undo = new_delta.compose(&undo).unwrap(); @@ -226,7 +226,7 @@ impl TestBuilder { } TestOp::AssertDocJson(delta_i, expected) => { - let delta_json = self.documents[*delta_i].to_json(); + let delta_json = self.documents[*delta_i].delta_str(); let expected_delta: RichTextDelta = serde_json::from_str(expected).unwrap(); let target_delta: RichTextDelta = serde_json::from_str(&delta_json).unwrap(); @@ -238,7 +238,7 @@ impl TestBuilder { } TestOp::AssertPrimeJson(doc_i, expected) => { - let prime_json = self.primes[*doc_i].as_ref().unwrap().to_delta_json(); + let prime_json = self.primes[*doc_i].as_ref().unwrap().to_delta_str(); let expected_prime: RichTextDelta = serde_json::from_str(expected).unwrap(); let target_prime: RichTextDelta = serde_json::from_str(&prime_json).unwrap(); 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 32366d667a..71c5e64dc3 100644 --- a/frontend/rust-lib/flowy-block/tests/editor/serde_test.rs +++ b/frontend/rust-lib/flowy-block/tests/editor/serde_test.rs @@ -92,7 +92,7 @@ fn delta_deserialize_null_test() { attribute.value = RichTextAttributeValue(None); let delta2 = DeltaBuilder::new().retain_with_attributes(7, attribute.into()).build(); - assert_eq!(delta2.to_delta_json(), r#"[{"retain":7,"attributes":{"bold":""}}]"#); + assert_eq!(delta2.to_delta_str(), r#"[{"retain":7,"attributes":{"bold":""}}]"#); assert_eq!(delta1, delta2); } @@ -108,10 +108,10 @@ fn document_insert_serde_test() { let mut document = ClientDocument::new::(); document.insert(0, "\n").unwrap(); document.insert(0, "123").unwrap(); - let json = document.to_json(); + let json = document.delta_str(); assert_eq!(r#"[{"insert":"123\n"}]"#, json); assert_eq!( r#"[{"insert":"123\n"}]"#, - ClientDocument::from_json(&json).unwrap().to_json() + ClientDocument::from_json(&json).unwrap().delta_str() ); } diff --git a/frontend/rust-lib/flowy-folder/Cargo.toml b/frontend/rust-lib/flowy-folder/Cargo.toml index 57e659ddd1..afb2ad54c7 100644 --- a/frontend/rust-lib/flowy-folder/Cargo.toml +++ b/frontend/rust-lib/flowy-folder/Cargo.toml @@ -42,6 +42,7 @@ bytes = { version = "1.0" } crossbeam = "0.8" crossbeam-utils = "0.8" chrono = "0.4" +async-trait = "0.1.52" [dev-dependencies] serial_test = "0.5.1" diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 34dca68c4e..4038c4900c 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -1,17 +1,3 @@ -use bytes::Bytes; -use chrono::Utc; -use flowy_collaboration::client_document::default::{initial_quill_delta, initial_quill_delta_string, initial_read_me}; -use flowy_folder_data_model::user_default; -use flowy_sync::RevisionWebSocket; -use lazy_static::lazy_static; - -use flowy_block::BlockManager; -use flowy_collaboration::{client_folder::FolderPad, entities::ws_data::ServerRevisionWSData}; - -use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; -use std::{collections::HashMap, convert::TryInto, fmt::Formatter, sync::Arc}; -use tokio::sync::RwLock as TokioRwLock; - use crate::{ dart_notification::{send_dart_notification, FolderNotification}, entities::workspace::RepeatedWorkspace, @@ -22,11 +8,22 @@ use crate::{ TrashController, ViewController, WorkspaceController, }, }; - +use async_trait::async_trait; +use bytes::Bytes; +use chrono::Utc; +use flowy_block::BlockManager; +use flowy_collaboration::client_document::default::{initial_quill_delta, initial_quill_delta_string, initial_read_me}; +use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; +use flowy_collaboration::{client_folder::FolderPad, entities::ws_data::ServerRevisionWSData}; +use flowy_folder_data_model::entities::view::ViewDataType; +use flowy_folder_data_model::user_default; +use flowy_sync::RevisionWebSocket; +use lazy_static::lazy_static; +use std::{collections::HashMap, convert::TryInto, fmt::Formatter, sync::Arc}; +use tokio::sync::RwLock as TokioRwLock; lazy_static! { static ref INIT_FOLDER_FLAG: TokioRwLock> = TokioRwLock::new(HashMap::new()); } - const FOLDER_ID: &str = "folder"; const FOLDER_ID_SPLIT: &str = ":"; #[derive(Clone)] @@ -72,6 +69,7 @@ impl FolderManager { user: Arc, cloud_service: Arc, database: Arc, + data_processors: DataProcessorMap, block_manager: Arc, web_socket: Arc, ) -> Self { @@ -95,6 +93,7 @@ impl FolderManager { persistence.clone(), cloud_service.clone(), trash_controller.clone(), + data_processors, block_manager, )); @@ -197,7 +196,7 @@ impl DefaultFolderBuilder { for app in workspace.apps.iter() { for (index, view) in app.belongings.iter().enumerate() { let view_data = if index == 0 { - initial_read_me().to_delta_json() + initial_read_me().to_delta_str() } else { initial_quill_delta_string() }; @@ -222,3 +221,14 @@ impl FolderManager { self.folder_editor.read().await.clone().unwrap() } } + +#[async_trait] +pub trait ViewDataProcessor { + async fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FlowyResult<()>; + async fn delete_container(&self, view_id: &str) -> FlowyResult<()>; + async fn close_container(&self, view_id: &str) -> FlowyResult<()>; + async fn delta_str(&self, view_id: &str) -> FlowyResult; + fn data_type(&self) -> ViewDataType; +} + +pub type DataProcessorMap = Arc>>; 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 e9c16cce16..ab27b49113 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -6,8 +6,10 @@ use flowy_collaboration::entities::{ use flowy_collaboration::client_document::default::initial_quill_delta_string; use futures::{FutureExt, StreamExt}; +use std::collections::HashMap; use std::{collections::HashSet, sync::Arc}; +use crate::manager::DataProcessorMap; use crate::{ dart_notification::{send_dart_notification, FolderNotification}, entities::{ @@ -23,6 +25,7 @@ use crate::{ }; use flowy_block::BlockManager; use flowy_database::kv::KV; +use flowy_folder_data_model::entities::view::ViewDataType; use lib_infra::uuid; const LATEST_VIEW_ID: &str = "latest_view_id"; @@ -32,6 +35,7 @@ pub(crate) struct ViewController { cloud_service: Arc, persistence: Arc, trash_controller: Arc, + data_processors: DataProcessorMap, block_manager: Arc, } @@ -40,15 +44,17 @@ impl ViewController { user: Arc, persistence: Arc, cloud_service: Arc, - trash_can: Arc, - document_manager: Arc, + trash_controller: Arc, + data_processors: DataProcessorMap, + block_manager: Arc, ) -> Self { Self { user, cloud_service, persistence, - trash_controller: trash_can, - block_manager: document_manager, + trash_controller, + data_processors, + block_manager, } } @@ -127,11 +133,11 @@ impl ViewController { #[tracing::instrument(level = "debug", skip(self), err)] pub(crate) async fn open_view(&self, view_id: &str) -> Result { let editor = self.block_manager.open_block(view_id).await?; + let delta_str = editor.delta_str().await?; KV::set_str(LATEST_VIEW_ID, view_id.to_owned()); - let document_json = editor.block_json().await?; Ok(BlockDelta { block_id: view_id.to_string(), - delta_json: document_json, + delta_str, }) } @@ -160,14 +166,14 @@ impl ViewController { .await?; let editor = self.block_manager.open_block(view_id).await?; - let document_json = editor.block_json().await?; + let delta_str = editor.delta_str().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: document_json, + data: delta_str, view_id: uuid(), ext_data: view.ext_data, plugin_type: view.plugin_type, @@ -208,11 +214,6 @@ impl ViewController { Ok(view) } - pub(crate) async fn receive_delta(&self, params: BlockDelta) -> Result { - let doc = self.block_manager.receive_local_delta(params).await?; - Ok(doc) - } - pub(crate) async fn latest_visit_view(&self) -> FlowyResult> { match KV::get_str(LATEST_VIEW_ID) { None => Ok(None), @@ -311,10 +312,10 @@ impl ViewController { } } -#[tracing::instrument(level = "trace", skip(persistence, document_manager, trash_can))] +#[tracing::instrument(level = "trace", skip(persistence, block_manager, trash_can))] async fn handle_trash_event( persistence: Arc, - document_manager: Arc, + block_manager: Arc, trash_can: Arc, event: TrashEvent, ) { @@ -352,7 +353,7 @@ async fn handle_trash_event( for identifier in identifiers.items { let view = transaction.read_view(&identifier.id)?; let _ = transaction.delete_view(&identifier.id)?; - let _ = document_manager.delete(&identifier.id)?; + let _ = block_manager.delete_block(&identifier.id)?; notify_ids.insert(view.belong_to_id); } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index ad521cfe59..8044a96ca3 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -41,29 +41,8 @@ impl GridManager { } #[tracing::instrument(level = "debug", skip_all, err)] - pub async fn create_grid>( - &self, - grid_id: T, - fields: Option>, - rows: Option>, - ) -> FlowyResult<()> { + pub async fn create_grid>(&self, grid_id: T, revisions: RepeatedRevision) -> FlowyResult<()> { let grid_id = grid_id.as_ref(); - let user_id = self.grid_user.user_id()?; - let mut field_orders = vec![]; - let mut row_orders = vec![]; - if let Some(fields) = fields { - field_orders = fields.iter().map(|field| FieldOrder::from(field)).collect::>(); - } - if let Some(rows) = rows { - row_orders = rows.iter().map(|row| RowOrder::from(row)).collect::>(); - } - - let grid = Grid { - id: grid_id.to_owned(), - field_orders: field_orders.into(), - row_orders: row_orders.into(), - }; - let revisions = make_grid_revisions(&user_id, &grid); let db_pool = self.grid_user.db_pool()?; let rev_manager = self.make_grid_rev_manager(grid_id, db_pool)?; let _ = rev_manager.reset_object(revisions).await?; @@ -144,6 +123,30 @@ impl GridManager { } } +pub fn make_grid( + user_id: &str, + grid_id: &str, + fields: Option>, + rows: Option>, +) -> RepeatedRevision { + let mut field_orders = vec![]; + let mut row_orders = vec![]; + if let Some(fields) = fields { + field_orders = fields.iter().map(|field| FieldOrder::from(field)).collect::>(); + } + if let Some(rows) = rows { + row_orders = rows.iter().map(|row| RowOrder::from(row)).collect::>(); + } + + let grid = Grid { + id: grid_id.to_owned(), + field_orders: field_orders.into(), + row_orders: row_orders.into(), + }; + + make_grid_revisions(user_id, &grid) +} + pub struct GridEditors { inner: DashMap>, } 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 4e692df48c..421111320a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -155,6 +155,10 @@ impl ClientGridEditor { self.grid_pad.read().await.grid_data() } + pub async fn delta_str(&self) -> String { + self.grid_pad.read().await.delta_str() + } + async fn modify(&self, f: F) -> FlowyResult<()> where F: for<'a> FnOnce(&'a mut GridPad) -> FlowyResult>, diff --git a/frontend/rust-lib/flowy-sdk/Cargo.toml b/frontend/rust-lib/flowy-sdk/Cargo.toml index c20b1cda62..01f9678f1c 100644 --- a/frontend/rust-lib/flowy-sdk/Cargo.toml +++ b/frontend/rust-lib/flowy-sdk/Cargo.toml @@ -23,7 +23,7 @@ color-eyre = { version = "0.5", default-features = false } bytes = "1.0" tokio = { version = "1", features = ["rt"] } parking_lot = "0.11" - +async-trait = "0.1.52" flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration" } lib-ws = { path = "../../../shared-lib/lib-ws" } 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 9e79c8c477..0fbddefa5f 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,12 +1,17 @@ +use async_trait::async_trait; use bytes::Bytes; use flowy_block::BlockManager; +use flowy_collaboration::entities::revision::RepeatedRevision; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; +use flowy_folder::manager::{DataProcessorMap, ViewDataProcessor}; +use flowy_folder::prelude::{FlowyResult, ViewDataType}; use flowy_folder::{ errors::{internal_error, FlowyError}, event_map::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser}, manager::FolderManager, }; +use flowy_grid::manager::GridManager; use flowy_net::ClientServerConfiguration; use flowy_net::{ http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect, @@ -16,6 +21,7 @@ use flowy_user::services::UserSession; use futures_core::future::BoxFuture; use lib_infra::future::BoxResultFuture; use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage}; +use std::collections::HashMap; use std::{convert::TryInto, sync::Arc}; pub struct FolderDepsResolver(); @@ -24,8 +30,9 @@ impl FolderDepsResolver { local_server: Option>, user_session: Arc, server_config: &ClientServerConfiguration, + ws_conn: &Arc, block_manager: &Arc, - ws_conn: Arc, + grid_manager: &Arc, ) -> Arc { let user: Arc = Arc::new(WorkspaceUserImpl(user_session.clone())); let database: Arc = Arc::new(WorkspaceDatabaseImpl(user_session)); @@ -35,8 +42,17 @@ impl FolderDepsResolver { Some(local_server) => local_server, }; + let view_data_processor = make_view_data_processor(block_manager.clone(), grid_manager.clone()); let folder_manager = Arc::new( - FolderManager::new(user.clone(), cloud_service, database, block_manager.clone(), web_socket).await, + FolderManager::new( + user.clone(), + cloud_service, + database, + view_data_processor, + block_manager.clone(), + web_socket, + ) + .await, ); if let (Ok(user_id), Ok(token)) = (user.user_id(), user.token()) { @@ -53,6 +69,18 @@ impl FolderDepsResolver { } } +fn make_view_data_processor(block_manager: Arc, grid_manager: Arc) -> DataProcessorMap { + let mut map: HashMap> = HashMap::new(); + + let block_data_impl = BlockManagerViewDataImpl(block_manager); + map.insert(block_data_impl.data_type(), Arc::new(block_data_impl)); + + let grid_data_impl = GridManagerViewDataImpl(grid_manager); + map.insert(grid_data_impl.data_type(), Arc::new(grid_data_impl)); + + Arc::new(map) +} + struct WorkspaceDatabaseImpl(Arc); impl WorkspaceDatabase for WorkspaceDatabaseImpl { fn db_pool(&self) -> Result, FlowyError> { @@ -110,3 +138,61 @@ impl WSMessageReceiver for FolderWSMessageReceiverImpl { }); } } + +struct BlockManagerViewDataImpl(Arc); +#[async_trait] +impl ViewDataProcessor for BlockManagerViewDataImpl { + async fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FlowyResult<()> { + let _ = self.0.create_block(view_id, repeated_revision).await?; + Ok(()) + } + + async fn delete_container(&self, view_id: &str) -> FlowyResult<()> { + let _ = self.0.delete_block(view_id)?; + Ok(()) + } + + async fn close_container(&self, view_id: &str) -> FlowyResult<()> { + let _ = self.0.close_block(view_id)?; + Ok(()) + } + + async fn delta_str(&self, view_id: &str) -> FlowyResult { + let editor = self.0.open_block(view_id).await?; + let delta_str = editor.delta_str().await?; + Ok(delta_str) + } + + fn data_type(&self) -> ViewDataType { + ViewDataType::RichText + } +} + +struct GridManagerViewDataImpl(Arc); +#[async_trait] +impl ViewDataProcessor for GridManagerViewDataImpl { + async fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FlowyResult<()> { + let _ = self.0.create_grid(view_id, repeated_revision).await?; + Ok(()) + } + + async fn delete_container(&self, view_id: &str) -> FlowyResult<()> { + let _ = self.0.delete_grid(view_id)?; + Ok(()) + } + + async fn close_container(&self, view_id: &str) -> FlowyResult<()> { + let _ = self.0.close_grid(view_id)?; + Ok(()) + } + + async fn delta_str(&self, view_id: &str) -> FlowyResult { + let editor = self.0.open_grid(view_id).await?; + let delta_str = editor.delta_str().await; + Ok(delta_str) + } + + fn data_type(&self) -> ViewDataType { + ViewDataType::Grid + } +} diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index 2390601fce..bb3b12aa6e 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -111,17 +111,18 @@ impl FlowySDK { &config.server_config, ); + let grid_manager = GridDepsResolver::resolve(ws_conn.clone(), user_session.clone()); + let folder_manager = FolderDepsResolver::resolve( local_server.clone(), user_session.clone(), &config.server_config, + &ws_conn, &block_manager, - ws_conn.clone(), + &grid_manager, ) .await; - let grid_manager = GridDepsResolver::resolve(ws_conn.clone(), user_session.clone()); - if let Some(local_server) = local_server.as_ref() { local_server.run(); } 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 0466093bda..be6b679c81 100644 --- a/shared-lib/flowy-collaboration/src/client_document/default/mod.rs +++ b/shared-lib/flowy-collaboration/src/client_document/default/mod.rs @@ -7,7 +7,7 @@ pub fn initial_quill_delta() -> RichTextDelta { #[inline] pub fn initial_quill_delta_string() -> String { - initial_quill_delta().to_delta_json() + initial_quill_delta().to_delta_str() } #[inline] @@ -22,6 +22,6 @@ mod tests { #[test] fn load_read_me() { - println!("{}", initial_read_me().to_delta_json()); + println!("{}", initial_read_me().to_delta_str()); } } 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 9f3bbe434b..0a537a8c8d 100644 --- a/shared-lib/flowy-collaboration/src/client_document/document_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_document/document_pad.rs @@ -58,8 +58,8 @@ impl ClientDocument { Ok(Self::from_delta(delta)) } - pub fn to_json(&self) -> String { - self.delta.to_delta_json() + pub fn delta_str(&self) -> String { + self.delta.to_delta_str() } pub fn to_bytes(&self) -> Vec { @@ -84,7 +84,7 @@ impl ClientDocument { } pub fn set_delta(&mut self, data: RichTextDelta) { - tracing::trace!("document: {}", data.to_delta_json()); + tracing::trace!("document: {}", data.to_delta_str()); self.delta = data; match &self.notify { @@ -96,7 +96,7 @@ impl ClientDocument { } pub fn compose_delta(&mut self, delta: RichTextDelta) -> Result<(), CollaborateError> { - tracing::trace!("{} compose {}", &self.delta.to_delta_json(), delta.to_delta_json()); + tracing::trace!("{} compose {}", &self.delta.to_delta_str(), delta.to_delta_str()); let composed_delta = self.delta.compose(&delta)?; let mut undo_delta = delta.invert(&self.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 4db744fc08..0b970d0bfa 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -86,6 +86,10 @@ impl GridPad { grid_ref.clone() } + pub fn delta_str(&self) -> String { + self.delta.to_delta_str() + } + pub fn field_orders(&self) -> &RepeatedFieldOrder { &self.grid.field_orders } diff --git a/shared-lib/flowy-collaboration/src/entities/document_info.rs b/shared-lib/flowy-collaboration/src/entities/document_info.rs index 1cb23027f5..e0701e3d56 100644 --- a/shared-lib/flowy-collaboration/src/entities/document_info.rs +++ b/shared-lib/flowy-collaboration/src/entities/document_info.rs @@ -46,7 +46,7 @@ impl std::convert::TryFrom for BlockInfo { } let delta = RichTextDelta::from_bytes(&revision.delta_data)?; - let doc_json = delta.to_delta_json(); + let doc_json = delta.to_delta_str(); Ok(BlockInfo { block_id: revision.object_id, @@ -72,7 +72,7 @@ pub struct BlockDelta { pub block_id: String, #[pb(index = 2)] - pub delta_json: String, + pub delta_str: String, } #[derive(ProtoBuf, Default, Debug, Clone)] diff --git a/shared-lib/flowy-collaboration/src/entities/revision.rs b/shared-lib/flowy-collaboration/src/entities/revision.rs index 48853fa9ed..cd99a194a1 100644 --- a/shared-lib/flowy-collaboration/src/entities/revision.rs +++ b/shared-lib/flowy-collaboration/src/entities/revision.rs @@ -89,7 +89,7 @@ impl std::fmt::Debug for Revision { let _ = f.write_fmt(format_args!("rev_id {}, ", self.rev_id))?; match RichTextDelta::from_bytes(&self.delta_data) { Ok(delta) => { - let _ = f.write_fmt(format_args!("delta {:?}", delta.to_delta_json()))?; + let _ = f.write_fmt(format_args!("delta {:?}", delta.to_delta_str()))?; } Err(e) => { let _ = f.write_fmt(format_args!("delta {:?}", e))?; diff --git a/shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs b/shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs index e2c9f5980c..28b3eb6bde 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs +++ b/shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs @@ -730,7 +730,7 @@ impl ::protobuf::reflect::ProtobufValue for ResetBlockParams { pub struct BlockDelta { // message fields pub block_id: ::std::string::String, - pub delta_json: ::std::string::String, + pub delta_str: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -773,30 +773,30 @@ impl BlockDelta { ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) } - // string delta_json = 2; + // string delta_str = 2; - pub fn get_delta_json(&self) -> &str { - &self.delta_json + pub fn get_delta_str(&self) -> &str { + &self.delta_str } - pub fn clear_delta_json(&mut self) { - self.delta_json.clear(); + pub fn clear_delta_str(&mut self) { + self.delta_str.clear(); } // Param is passed by value, moved - pub fn set_delta_json(&mut self, v: ::std::string::String) { - self.delta_json = v; + pub fn set_delta_str(&mut self, v: ::std::string::String) { + self.delta_str = v; } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_delta_json(&mut self) -> &mut ::std::string::String { - &mut self.delta_json + pub fn mut_delta_str(&mut self) -> &mut ::std::string::String { + &mut self.delta_str } // Take field - pub fn take_delta_json(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.delta_json, ::std::string::String::new()) + pub fn take_delta_str(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.delta_str, ::std::string::String::new()) } } @@ -813,7 +813,7 @@ impl ::protobuf::Message for BlockDelta { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; }, 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.delta_json)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.delta_str)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -830,8 +830,8 @@ impl ::protobuf::Message for BlockDelta { if !self.block_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.block_id); } - if !self.delta_json.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.delta_json); + if !self.delta_str.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.delta_str); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -842,8 +842,8 @@ impl ::protobuf::Message for BlockDelta { if !self.block_id.is_empty() { os.write_string(1, &self.block_id)?; } - if !self.delta_json.is_empty() { - os.write_string(2, &self.delta_json)?; + if !self.delta_str.is_empty() { + os.write_string(2, &self.delta_str)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -889,9 +889,9 @@ impl ::protobuf::Message for BlockDelta { |m: &mut BlockDelta| { &mut m.block_id }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "delta_json", - |m: &BlockDelta| { &m.delta_json }, - |m: &mut BlockDelta| { &mut m.delta_json }, + "delta_str", + |m: &BlockDelta| { &m.delta_str }, + |m: &mut BlockDelta| { &mut m.delta_str }, )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "BlockDelta", @@ -910,7 +910,7 @@ impl ::protobuf::Message for BlockDelta { impl ::protobuf::Clear for BlockDelta { fn clear(&mut self) { self.block_id.clear(); - self.delta_json.clear(); + self.delta_str.clear(); self.unknown_fields.clear(); } } @@ -1330,9 +1330,9 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \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\"F\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\ - \x1d\n\ndelta_json\x18\x02\x20\x01(\tR\tdeltaJson\"S\n\nNewDocUser\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\ diff --git a/shared-lib/flowy-collaboration/src/protobuf/proto/document_info.proto b/shared-lib/flowy-collaboration/src/protobuf/proto/document_info.proto index 32d6102c34..9190b581a5 100644 --- a/shared-lib/flowy-collaboration/src/protobuf/proto/document_info.proto +++ b/shared-lib/flowy-collaboration/src/protobuf/proto/document_info.proto @@ -17,7 +17,7 @@ message ResetBlockParams { } message BlockDelta { string block_id = 1; - string delta_json = 2; + string delta_str = 2; } message NewDocUser { string user_id = 1; diff --git a/shared-lib/flowy-collaboration/src/server_document/document_pad.rs b/shared-lib/flowy-collaboration/src/server_document/document_pad.rs index 766fc5cb2a..1f4fa7bda1 100644 --- a/shared-lib/flowy-collaboration/src/server_document/document_pad.rs +++ b/shared-lib/flowy-collaboration/src/server_document/document_pad.rs @@ -39,7 +39,7 @@ impl RevisionSyncObject for ServerDocument { } fn to_json(&self) -> String { - self.delta.to_delta_json() + self.delta.to_delta_str() } fn set_delta(&mut self, new_delta: Delta) { diff --git a/shared-lib/flowy-collaboration/src/server_folder/folder_pad.rs b/shared-lib/flowy-collaboration/src/server_folder/folder_pad.rs index eb1d6aa9dc..3b51e52ed7 100644 --- a/shared-lib/flowy-collaboration/src/server_folder/folder_pad.rs +++ b/shared-lib/flowy-collaboration/src/server_folder/folder_pad.rs @@ -32,7 +32,7 @@ impl RevisionSyncObject for ServerFolder { } fn to_json(&self) -> String { - self.delta.to_delta_json() + self.delta.to_delta_str() } fn set_delta(&mut self, new_delta: PlainTextDelta) { diff --git a/shared-lib/flowy-collaboration/src/util.rs b/shared-lib/flowy-collaboration/src/util.rs index 97be40431d..6953949961 100644 --- a/shared-lib/flowy-collaboration/src/util.rs +++ b/shared-lib/flowy-collaboration/src/util.rs @@ -189,7 +189,7 @@ pub fn make_folder_pb_from_revisions_pb( folder_delta = folder_delta.compose(&delta)?; } - let text = folder_delta.to_delta_json(); + let text = folder_delta.to_delta_str(); let mut folder_info = FolderInfoPB::new(); folder_info.set_folder_id(folder_id.to_owned()); folder_info.set_text(text); @@ -239,7 +239,7 @@ pub fn make_document_info_pb_from_revisions_pb( document_delta = document_delta.compose(&delta)?; } - let text = document_delta.to_delta_json(); + let text = document_delta.to_delta_str(); let mut block_info = BlockInfoPB::new(); block_info.set_block_id(doc_id.to_owned()); block_info.set_text(text); 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 53a6bd8caa..87065659b6 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/view.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/view.rs @@ -80,7 +80,7 @@ impl std::convert::From for Trash { } } -#[derive(Eq, PartialEq, Debug, ProtoBuf_Enum, Clone, Serialize_repr, Deserialize_repr)] +#[derive(Eq, PartialEq, Hash, Debug, ProtoBuf_Enum, Clone, Serialize_repr, Deserialize_repr)] #[repr(u8)] pub enum ViewDataType { RichText = 0, diff --git a/shared-lib/lib-ot/src/core/delta/delta.rs b/shared-lib/lib-ot/src/core/delta/delta.rs index 94dd904217..e9a7e15e12 100644 --- a/shared-lib/lib-ot/src/core/delta/delta.rs +++ b/shared-lib/lib-ot/src/core/delta/delta.rs @@ -521,7 +521,7 @@ impl Delta where T: Attributes + serde::Serialize, { - pub fn to_delta_json(&self) -> String { + pub fn to_delta_str(&self) -> String { serde_json::to_string(self).unwrap_or_else(|_| "".to_owned()) } @@ -530,7 +530,7 @@ where } pub fn to_bytes(&self) -> Bytes { - let json = self.to_delta_json(); + let json = self.to_delta_str(); Bytes::from(json.into_bytes()) } } From 264166fa293eebe61eeac63c31490d5c8a6f1b00 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 6 Mar 2022 09:03:02 +0800 Subject: [PATCH 15/17] chore: impl view data processor --- .../workspace/application/doc/doc_bloc.dart | 6 +- .../application/doc/doc_service.dart | 7 +- .../presentation/plugins/grid/grid.dart | 5 +- frontend/rust-lib/Cargo.lock | 3 +- frontend/rust-lib/flowy-folder/Cargo.toml | 2 +- frontend/rust-lib/flowy-folder/src/manager.rs | 45 +++-- .../src/services/view/controller.rs | 157 ++++++++++++------ .../rust-lib/flowy-grid/src/event_handler.rs | 5 +- frontend/rust-lib/flowy-grid/src/manager.rs | 73 +++++--- .../flowy-grid/src/services/cell_data.rs | 20 +-- .../flowy-grid/src/services/grid_editor.rs | 11 +- .../flowy-grid/src/services/kv_persistence.rs | 6 +- .../flowy-grid/src/services/stringify.rs | 1 + frontend/rust-lib/flowy-sdk/Cargo.toml | 1 - .../flowy-sdk/src/deps_resolve/folder_deps.rs | 129 +++++++++----- .../flowy-sdk/src/deps_resolve/grid_deps.rs | 5 +- frontend/rust-lib/flowy-sdk/src/module.rs | 3 +- .../src/client_folder/folder_pad.rs | 2 +- .../src/client_grid/grid_pad.rs | 8 +- .../flowy-grid-data-model/tests/serde_test.rs | 1 + 20 files changed, 305 insertions(+), 185 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart b/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart index e3dc9c91aa..d08b108f15 100644 --- a/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart @@ -85,10 +85,10 @@ class DocumentBloc extends Bloc { }); listener.start(); - final result = await service.openDocument(docId: view.id); + final result = await service.openDocument(docId: view.id, dataType: view.dataType); result.fold( (block) { - document = _decodeJsonToDocument(block.deltaJson); + document = _decodeJsonToDocument(block.deltaStr); _subscription = document.changes.listen((event) { final delta = event.item2; final documentDelta = document.toDelta(); @@ -115,7 +115,7 @@ class DocumentBloc extends Bloc { result.fold((rustDoc) { // final json = utf8.decode(doc.data); - final rustDelta = Delta.fromJson(jsonDecode(rustDoc.deltaJson)); + final rustDelta = Delta.fromJson(jsonDecode(rustDoc.deltaStr)); if (documentDelta != rustDelta) { Log.error("Receive : $rustDelta"); Log.error("Expected : $documentDelta"); diff --git a/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart b/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart index e0891ea62c..e107dda5ee 100644 --- a/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart +++ b/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart @@ -5,7 +5,10 @@ import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; class DocumentService { - Future> openDocument({required String docId}) { + Future> openDocument({ + required String docId, + required ViewDataType dataType, + }) { final request = ViewId(value: docId); return FolderEventOpenView(request).send(); } @@ -13,7 +16,7 @@ class DocumentService { Future> composeDelta({required String docId, required String data}) { final request = BlockDelta.create() ..blockId = docId - ..deltaJson = data; + ..deltaStr = data; return FolderEventApplyDocDelta(request).send(); } 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 0fca5db0c7..0aa7237a7d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart @@ -6,7 +6,7 @@ import 'package:flutter/material.dart'; import 'src/grid_page.dart'; -class GridPluginBuilder extends PluginBuilder { +class GridPluginBuilder implements PluginBuilder { @override Plugin build(dynamic data) { if (data is View) { @@ -21,6 +21,9 @@ class GridPluginBuilder extends PluginBuilder { @override PluginType get pluginType => DefaultPlugin.grid.type(); + + @override + ViewDataType get dataType => ViewDataType.Grid; } class GridPluginConfig implements PluginConfig { diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 4dd16b94db..6b22e06e0a 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -986,13 +986,13 @@ dependencies = [ name = "flowy-folder" version = "0.1.0" dependencies = [ - "async-trait", "bincode", "bytes", "chrono", "crossbeam", "crossbeam-utils", "dart-notify", + "dashmap", "derive_more", "diesel", "diesel_derives", @@ -1134,7 +1134,6 @@ dependencies = [ name = "flowy-sdk" version = "0.1.0" dependencies = [ - "async-trait", "bincode", "bytes", "claim 0.5.0", diff --git a/frontend/rust-lib/flowy-folder/Cargo.toml b/frontend/rust-lib/flowy-folder/Cargo.toml index afb2ad54c7..126b2828db 100644 --- a/frontend/rust-lib/flowy-folder/Cargo.toml +++ b/frontend/rust-lib/flowy-folder/Cargo.toml @@ -42,7 +42,7 @@ bytes = { version = "1.0" } crossbeam = "0.8" crossbeam-utils = "0.8" chrono = "0.4" -async-trait = "0.1.52" +dashmap = "4.0" [dev-dependencies] serial_test = "0.5.1" diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 4038c4900c..713ab9e3b3 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -8,17 +8,18 @@ use crate::{ TrashController, ViewController, WorkspaceController, }, }; -use async_trait::async_trait; use bytes::Bytes; use chrono::Utc; -use flowy_block::BlockManager; -use flowy_collaboration::client_document::default::{initial_quill_delta, initial_quill_delta_string, initial_read_me}; -use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; + +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; use flowy_folder_data_model::user_default; use flowy_sync::RevisionWebSocket; use lazy_static::lazy_static; +use lib_infra::future::FutureResult; use std::{collections::HashMap, convert::TryInto, fmt::Formatter, sync::Arc}; use tokio::sync::RwLock as TokioRwLock; lazy_static! { @@ -62,6 +63,7 @@ pub struct FolderManager { pub(crate) trash_controller: Arc, web_socket: Arc, folder_editor: Arc>>>, + data_processors: ViewDataProcessorMap, } impl FolderManager { @@ -69,8 +71,7 @@ impl FolderManager { user: Arc, cloud_service: Arc, database: Arc, - data_processors: DataProcessorMap, - block_manager: Arc, + data_processors: ViewDataProcessorMap, web_socket: Arc, ) -> Self { if let Ok(user_id) = user.user_id() { @@ -93,8 +94,7 @@ impl FolderManager { persistence.clone(), cloud_service.clone(), trash_controller.clone(), - data_processors, - block_manager, + data_processors.clone(), )); let app_controller = Arc::new(AppController::new( @@ -121,6 +121,7 @@ impl FolderManager { trash_controller, web_socket, folder_editor, + data_processors, } } @@ -167,6 +168,11 @@ impl FolderManager { let _ = self.app_controller.initialize()?; let _ = self.view_controller.initialize()?; + + self.data_processors.iter().for_each(|(_, processor)| { + processor.initialize(); + }); + write_guard.insert(user_id.to_owned(), true); Ok(()) } @@ -201,7 +207,9 @@ impl DefaultFolderBuilder { initial_quill_delta_string() }; view_controller.set_latest_view(view); - let _ = view_controller.create_view(&view.id, Bytes::from(view_data)).await?; + let _ = view_controller + .create_view(&view.id, ViewDataType::RichText, Bytes::from(view_data)) + .await?; } } let folder = FolderPad::new(vec![workspace.clone()], vec![])?; @@ -222,13 +230,20 @@ impl FolderManager { } } -#[async_trait] pub trait ViewDataProcessor { - async fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FlowyResult<()>; - async fn delete_container(&self, view_id: &str) -> FlowyResult<()>; - async fn close_container(&self, view_id: &str) -> FlowyResult<()>; - async fn delta_str(&self, view_id: &str) -> FlowyResult; + fn initialize(&self) -> FutureResult<(), FlowyError>; + + fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FutureResult<(), FlowyError>; + + fn delete_container(&self, view_id: &str) -> FutureResult<(), FlowyError>; + + fn close_container(&self, view_id: &str) -> FutureResult<(), FlowyError>; + + fn delta_str(&self, view_id: &str) -> FutureResult; + + fn default_view_data(&self) -> String; + fn data_type(&self) -> ViewDataType; } -pub type DataProcessorMap = Arc>>; +pub type ViewDataProcessorMap = Arc>>; 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 ab27b49113..455bd78c44 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -1,15 +1,4 @@ -use bytes::Bytes; -use flowy_collaboration::entities::{ - document_info::{BlockDelta, BlockId}, - revision::{RepeatedRevision, Revision}, -}; - -use flowy_collaboration::client_document::default::initial_quill_delta_string; -use futures::{FutureExt, StreamExt}; -use std::collections::HashMap; -use std::{collections::HashSet, sync::Arc}; - -use crate::manager::DataProcessorMap; +use crate::manager::{ViewDataProcessor, ViewDataProcessorMap}; use crate::{ dart_notification::{send_dart_notification, FolderNotification}, entities::{ @@ -23,10 +12,16 @@ use crate::{ TrashController, TrashEvent, }, }; -use flowy_block::BlockManager; +use bytes::Bytes; +use flowy_collaboration::entities::{ + document_info::{BlockDelta, BlockId}, + revision::{RepeatedRevision, Revision}, +}; use flowy_database::kv::KV; use flowy_folder_data_model::entities::view::ViewDataType; +use futures::{FutureExt, StreamExt}; use lib_infra::uuid; +use std::{collections::HashSet, sync::Arc}; const LATEST_VIEW_ID: &str = "latest_view_id"; @@ -35,8 +30,7 @@ pub(crate) struct ViewController { cloud_service: Arc, persistence: Arc, trash_controller: Arc, - data_processors: DataProcessorMap, - block_manager: Arc, + data_processors: ViewDataProcessorMap, } impl ViewController { @@ -45,8 +39,7 @@ impl ViewController { persistence: Arc, cloud_service: Arc, trash_controller: Arc, - data_processors: DataProcessorMap, - block_manager: Arc, + data_processors: ViewDataProcessorMap, ) -> Self { Self { user, @@ -54,38 +47,48 @@ impl ViewController { persistence, trash_controller, data_processors, - block_manager, } } pub(crate) fn initialize(&self) -> Result<(), FlowyError> { - let _ = self.block_manager.init()?; self.listen_trash_can_event(); Ok(()) } #[tracing::instrument(level = "trace", skip(self, params), fields(name = %params.name), err)] - pub(crate) async fn create_view_from_params(&self, params: CreateViewParams) -> Result { - let view_data = if params.data.is_empty() { - initial_quill_delta_string() + 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(); + params.data = default_view_data.clone(); + default_view_data } else { params.data.clone() }; - let _ = self.create_view(¶ms.view_id, Bytes::from(view_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) } #[tracing::instrument(level = "debug", skip(self, view_id, delta_data), err)] - pub(crate) async fn create_view(&self, view_id: &str, delta_data: Bytes) -> Result<(), FlowyError> { + pub(crate) async fn create_view( + &self, + view_id: &str, + data_type: ViewDataType, + delta_data: Bytes, + ) -> Result<(), FlowyError> { if delta_data.is_empty() { 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 _ = self.block_manager.create_block(view_id, repeated_revision).await?; + let processor = self.get_data_processor(&data_type)?; + let _ = processor.create_container(view_id, repeated_revision).await?; Ok(()) } @@ -132,8 +135,8 @@ impl ViewController { #[tracing::instrument(level = "debug", skip(self), err)] pub(crate) async fn open_view(&self, view_id: &str) -> Result { - let editor = self.block_manager.open_block(view_id).await?; - let delta_str = editor.delta_str().await?; + let processor = self.get_data_processor_from_view_id(view_id).await?; + let delta_str = processor.delta_str(view_id).await?; KV::set_str(LATEST_VIEW_ID, view_id.to_owned()); Ok(BlockDelta { block_id: view_id.to_string(), @@ -142,8 +145,9 @@ impl ViewController { } #[tracing::instrument(level = "debug", skip(self), err)] - pub(crate) async fn close_view(&self, doc_id: &str) -> Result<(), FlowyError> { - let _ = self.block_manager.close_block(doc_id)?; + pub(crate) async fn close_view(&self, view_id: &str) -> Result<(), FlowyError> { + let processor = self.get_data_processor_from_view_id(view_id).await?; + let _ = processor.close_container(view_id).await?; Ok(()) } @@ -154,7 +158,8 @@ impl ViewController { let _ = KV::remove(LATEST_VIEW_ID); } } - let _ = self.block_manager.close_block(¶ms.value)?; + let processor = self.get_data_processor_from_view_id(¶ms.value).await?; + let _ = processor.close_container(¶ms.value).await?; Ok(()) } @@ -165,8 +170,8 @@ impl ViewController { .begin_transaction(|transaction| transaction.read_view(view_id)) .await?; - let editor = self.block_manager.open_block(view_id).await?; - let delta_str = editor.delta_str().await?; + let processor = self.get_data_processor(&view.data_type)?; + let delta_str = processor.delta_str(view_id).await?; let duplicate_params = CreateViewParams { belong_to_id: view.belong_to_id.clone(), name: format!("{} (copy)", &view.name), @@ -287,7 +292,7 @@ impl ViewController { fn listen_trash_can_event(&self) { let mut rx = self.trash_controller.subscribe(); let persistence = self.persistence.clone(); - let block_manager = self.block_manager.clone(); + let data_processors = self.data_processors.clone(); let trash_controller = self.trash_controller.clone(); let _ = tokio::spawn(async move { loop { @@ -301,7 +306,7 @@ impl ViewController { if let Some(event) = stream.next().await { handle_trash_event( persistence.clone(), - block_manager.clone(), + data_processors.clone(), trash_controller.clone(), event, ) @@ -310,12 +315,34 @@ impl ViewController { } }); } + + async fn get_data_processor_from_view_id( + &self, + view_id: &str, + ) -> FlowyResult> { + let view = self + .persistence + .begin_transaction(|transaction| transaction.read_view(view_id)) + .await?; + self.get_data_processor(&view.data_type) + } + + #[inline] + fn get_data_processor(&self, data_type: &ViewDataType) -> FlowyResult> { + match self.data_processors.get(data_type) { + None => Err(FlowyError::internal().context(format!( + "Get data processor failed. Unknown view data type: {:?}", + data_type + ))), + Some(processor) => Ok(processor.clone()), + } + } } -#[tracing::instrument(level = "trace", skip(persistence, block_manager, trash_can))] +#[tracing::instrument(level = "trace", skip(persistence, data_processors, trash_can))] async fn handle_trash_event( persistence: Arc, - block_manager: Arc, + data_processors: ViewDataProcessorMap, trash_can: Arc, event: TrashEvent, ) { @@ -347,28 +374,54 @@ async fn handle_trash_event( let _ = ret.send(result).await; } TrashEvent::Delete(identifiers, ret) => { - let result = persistence - .begin_transaction(|transaction| { - let mut notify_ids = HashSet::new(); - for identifier in identifiers.items { - let view = transaction.read_view(&identifier.id)?; - let _ = transaction.delete_view(&identifier.id)?; - let _ = block_manager.delete_block(&identifier.id)?; - notify_ids.insert(view.belong_to_id); - } + let result = || async { + let views = persistence + .begin_transaction(|transaction| { + let mut notify_ids = HashSet::new(); + let mut views = vec![]; + for identifier in identifiers.items { + let view = transaction.read_view(&identifier.id)?; + let _ = transaction.delete_view(&view.id)?; + notify_ids.insert(view.belong_to_id.clone()); + views.push(view); + } + for notify_id in notify_ids { + let _ = notify_views_changed(¬ify_id, trash_can.clone(), &transaction)?; + } + Ok(views) + }) + .await?; - for notify_id in notify_ids { - let _ = notify_views_changed(¬ify_id, trash_can.clone(), &transaction)?; + for view in views { + match get_data_processor(data_processors.clone(), &view.data_type) { + Ok(processor) => { + let _ = processor.close_container(&view.id).await?; + } + Err(e) => { + tracing::error!("{}", e) + } } - - Ok(()) - }) - .await; - let _ = ret.send(result).await; + } + Ok(()) + }; + let _ = ret.send(result().await).await; } } } +fn get_data_processor( + data_processors: ViewDataProcessorMap, + data_type: &ViewDataType, +) -> FlowyResult> { + match data_processors.get(data_type) { + None => Err(FlowyError::internal().context(format!( + "Get data processor failed. Unknown view data type: {:?}", + data_type + ))), + Some(processor) => Ok(processor.clone()), + } +} + fn read_local_views_with_transaction<'a>( identifiers: RepeatedTrashId, transaction: &'a (dyn FolderPersistenceTransaction + 'a), diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index f8efe9f413..72e2272c03 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,9 +1,6 @@ use crate::manager::GridManager; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{ - CreateGridPayload, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedFieldOrder, - RepeatedRow, RepeatedRowOrder, -}; +use flowy_grid_data_model::entities::{Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedRow}; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 8044a96ca3..17acaad3fa 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -1,12 +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::client_grid::{make_grid_delta, make_grid_revisions}; +use flowy_collaboration::client_grid::make_grid_delta; use flowy_collaboration::entities::revision::RepeatedRevision; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{ - Field, FieldOrder, Grid, RawRow, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, RowOrder, -}; +use flowy_grid_data_model::entities::{Field, FieldOrder, FieldType, Grid, RawRow, RowOrder}; use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; use lib_sqlite::ConnectionPool; use parking_lot::RwLock; @@ -21,12 +19,11 @@ pub trait GridUser: Send + Sync { pub struct GridManager { grid_editors: Arc, grid_user: Arc, - rev_web_socket: Arc, kv_persistence: Arc>>>, } impl GridManager { - pub fn new(grid_user: Arc, rev_web_socket: Arc) -> Self { + pub fn new(grid_user: Arc, _rev_web_socket: Arc) -> Self { let grid_editors = Arc::new(GridEditors::new()); // kv_persistence will be initialized after first access. @@ -35,7 +32,6 @@ impl GridManager { Self { grid_editors, grid_user, - rev_web_socket, kv_persistence, } } @@ -123,28 +119,57 @@ impl GridManager { } } -pub fn make_grid( - user_id: &str, - grid_id: &str, - fields: Option>, - rows: Option>, -) -> RepeatedRevision { - let mut field_orders = vec![]; - let mut row_orders = vec![]; - if let Some(fields) = fields { - field_orders = fields.iter().map(|field| FieldOrder::from(field)).collect::>(); - } - if let Some(rows) = rows { - row_orders = rows.iter().map(|row| RowOrder::from(row)).collect::>(); - } +use lib_infra::uuid; +pub fn default_grid() -> String { + let grid_id = uuid(); + let fields = vec![ + Field { + id: uuid(), + name: "".to_string(), + desc: "".to_string(), + field_type: FieldType::RichText, + frozen: false, + width: 100, + type_options: Default::default(), + }, + Field { + id: uuid(), + name: "".to_string(), + desc: "".to_string(), + field_type: FieldType::RichText, + frozen: false, + width: 100, + type_options: Default::default(), + }, + ]; + + let rows = vec![ + RawRow { + id: uuid(), + grid_id: grid_id.clone(), + cell_by_field_id: Default::default(), + }, + RawRow { + id: uuid(), + grid_id: grid_id.clone(), + cell_by_field_id: Default::default(), + }, + ]; + + make_grid(&grid_id, fields, rows) +} + +pub fn make_grid(grid_id: &str, fields: Vec, rows: Vec) -> String { + let field_orders = fields.iter().map(FieldOrder::from).collect::>(); + let row_orders = rows.iter().map(RowOrder::from).collect::>(); let grid = Grid { id: grid_id.to_owned(), field_orders: field_orders.into(), row_orders: row_orders.into(), }; - - make_grid_revisions(user_id, &grid) + let delta = make_grid_delta(&grid); + delta.to_delta_str() } pub struct GridEditors { diff --git a/frontend/rust-lib/flowy-grid/src/services/cell_data.rs b/frontend/rust-lib/flowy-grid/src/services/cell_data.rs index afa278fcd3..64e4b374d2 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell_data.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell_data.rs @@ -1,3 +1,4 @@ +#![allow(clippy::upper_case_acronyms)] use crate::impl_any_data; use crate::services::util::*; use bytes::Bytes; @@ -12,8 +13,6 @@ use rusty_money::{ Money, }; use std::str::FromStr; - -use strum::IntoEnumIterator; use strum_macros::EnumIter; pub trait StringifyAnyData { @@ -77,7 +76,7 @@ impl DisplayCell for CheckboxDescription { } // Date -#[derive(Clone, Debug, ProtoBuf)] +#[derive(Clone, Debug, ProtoBuf, Default)] pub struct DateDescription { #[pb(index = 1)] pub date_format: DateFormat, @@ -87,15 +86,6 @@ pub struct DateDescription { } impl_any_data!(DateDescription, FieldType::DateTime); -impl std::default::Default for DateDescription { - fn default() -> Self { - DateDescription { - date_format: DateFormat::default(), - time_format: TimeFormat::default(), - } - } -} - impl DateDescription { fn date_time_format_str(&self) -> String { format!("{} {}", self.date_format.format_str(), self.time_format.format_str()) @@ -134,7 +124,7 @@ impl DisplayCell for DateDescription { impl StringifyAnyData for DateDescription { fn stringify_any_data(&self, data: AnyData) -> String { - match String::from_utf8(data.value.clone()) { + match String::from_utf8(data.value) { Ok(s) => match s.parse::() { Ok(timestamp) => { let native = NaiveDateTime::from_timestamp(timestamp, 0); @@ -380,7 +370,7 @@ impl NumberDescription { impl DisplayCell for NumberDescription { fn display_content(&self, s: &str) -> String { - match self.money_from_str(&s) { + match self.money_from_str(s) { Some(money_str) => money_str, None => String::default(), } @@ -389,7 +379,7 @@ impl DisplayCell for NumberDescription { impl StringifyAnyData for NumberDescription { fn stringify_any_data(&self, data: AnyData) -> String { - match String::from_utf8(data.value.clone()) { + match String::from_utf8(data.value) { Ok(s) => match self.money_from_str(&s) { Some(money_str) => money_str, None => String::default(), 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 421111320a..418807e058 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,23 +1,20 @@ use crate::manager::GridUser; use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use crate::services::stringify::stringify_deserialize; -use dashmap::mapref::one::Ref; + use dashmap::DashMap; use flowy_collaboration::client_grid::{GridChange, GridPad}; 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, GridId, RawCell, RawRow, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, -}; -use flowy_sync::{ - RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder, RevisionPersistence, - RevisionWebSocket, RevisionWebSocketManager, + Cell, Field, Grid, RawCell, RawRow, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, }; +use flowy_sync::{RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; use lib_infra::uuid; use lib_ot::core::PlainTextAttributes; -use lib_sqlite::ConnectionPool; + use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; use std::sync::Arc; 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 db3bdfdd7b..bc398f9cf3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs +++ b/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs @@ -6,9 +6,9 @@ use flowy_database::{ schema::{kv_table, kv_table::dsl}, }; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{Field, GridIdentifiable, RawRow}; -use lib_infra::future::{BoxResultFuture, FutureResult}; -use lib_sqlite::{ConnectionManager, ConnectionPool}; +use flowy_grid_data_model::entities::GridIdentifiable; + +use lib_sqlite::ConnectionPool; use std::sync::Arc; #[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] diff --git a/frontend/rust-lib/flowy-grid/src/services/stringify.rs b/frontend/rust-lib/flowy-grid/src/services/stringify.rs index 3eab8f91a5..a9154a5809 100644 --- a/frontend/rust-lib/flowy-grid/src/services/stringify.rs +++ b/frontend/rust-lib/flowy-grid/src/services/stringify.rs @@ -3,6 +3,7 @@ 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), diff --git a/frontend/rust-lib/flowy-sdk/Cargo.toml b/frontend/rust-lib/flowy-sdk/Cargo.toml index 01f9678f1c..75791d0279 100644 --- a/frontend/rust-lib/flowy-sdk/Cargo.toml +++ b/frontend/rust-lib/flowy-sdk/Cargo.toml @@ -23,7 +23,6 @@ color-eyre = { version = "0.5", default-features = false } bytes = "1.0" tokio = { version = "1", features = ["rt"] } parking_lot = "0.11" -async-trait = "0.1.52" flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration" } lib-ws = { path = "../../../shared-lib/lib-ws" } 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 0fbddefa5f..fc979937ad 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,17 +1,17 @@ -use async_trait::async_trait; use bytes::Bytes; use flowy_block::BlockManager; +use flowy_collaboration::client_document::default::initial_quill_delta_string; use flowy_collaboration::entities::revision::RepeatedRevision; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; -use flowy_folder::manager::{DataProcessorMap, ViewDataProcessor}; -use flowy_folder::prelude::{FlowyResult, ViewDataType}; +use flowy_folder::manager::{ViewDataProcessor, ViewDataProcessorMap}; +use flowy_folder::prelude::ViewDataType; use flowy_folder::{ errors::{internal_error, FlowyError}, event_map::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser}, manager::FolderManager, }; -use flowy_grid::manager::GridManager; +use flowy_grid::manager::{default_grid, GridManager}; use flowy_net::ClientServerConfiguration; use flowy_net::{ http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect, @@ -19,7 +19,7 @@ use flowy_net::{ use flowy_sync::{RevisionWebSocket, WSStateReceiver}; use flowy_user::services::UserSession; use futures_core::future::BoxFuture; -use lib_infra::future::BoxResultFuture; +use lib_infra::future::{BoxResultFuture, FutureResult}; use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage}; use std::collections::HashMap; use std::{convert::TryInto, sync::Arc}; @@ -43,17 +43,8 @@ impl FolderDepsResolver { }; let view_data_processor = make_view_data_processor(block_manager.clone(), grid_manager.clone()); - let folder_manager = Arc::new( - FolderManager::new( - user.clone(), - cloud_service, - database, - view_data_processor, - block_manager.clone(), - web_socket, - ) - .await, - ); + let folder_manager = + Arc::new(FolderManager::new(user.clone(), cloud_service, database, view_data_processor, web_socket).await); if let (Ok(user_id), Ok(token)) = (user.user_id(), user.token()) { match folder_manager.initialize(&user_id, &token).await { @@ -64,12 +55,11 @@ impl FolderDepsResolver { let receiver = Arc::new(FolderWSMessageReceiverImpl(folder_manager.clone())); ws_conn.add_ws_message_receiver(receiver).unwrap(); - folder_manager } } -fn make_view_data_processor(block_manager: Arc, grid_manager: Arc) -> DataProcessorMap { +fn make_view_data_processor(block_manager: Arc, grid_manager: Arc) -> ViewDataProcessorMap { let mut map: HashMap> = HashMap::new(); let block_data_impl = BlockManagerViewDataImpl(block_manager); @@ -140,27 +130,51 @@ impl WSMessageReceiver for FolderWSMessageReceiverImpl { } struct BlockManagerViewDataImpl(Arc); -#[async_trait] impl ViewDataProcessor for BlockManagerViewDataImpl { - async fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FlowyResult<()> { - let _ = self.0.create_block(view_id, repeated_revision).await?; - Ok(()) + fn initialize(&self) -> FutureResult<(), FlowyError> { + let block_manager = self.0.clone(); + FutureResult::new(async move { block_manager.init() }) } - async fn delete_container(&self, view_id: &str) -> FlowyResult<()> { - let _ = self.0.delete_block(view_id)?; - Ok(()) + fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FutureResult<(), FlowyError> { + let block_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?; + Ok(()) + }) } - async fn close_container(&self, view_id: &str) -> FlowyResult<()> { - let _ = self.0.close_block(view_id)?; - Ok(()) + fn delete_container(&self, view_id: &str) -> FutureResult<(), FlowyError> { + let block_manager = self.0.clone(); + let view_id = view_id.to_string(); + FutureResult::new(async move { + let _ = block_manager.delete_block(view_id)?; + Ok(()) + }) } - async fn delta_str(&self, view_id: &str) -> FlowyResult { - let editor = self.0.open_block(view_id).await?; - let delta_str = editor.delta_str().await?; - Ok(delta_str) + fn close_container(&self, view_id: &str) -> FutureResult<(), FlowyError> { + let block_manager = self.0.clone(); + let view_id = view_id.to_string(); + FutureResult::new(async move { + let _ = block_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(); + FutureResult::new(async move { + let editor = block_manager.open_block(view_id).await?; + let delta_str = editor.delta_str().await?; + Ok(delta_str) + }) + } + + fn default_view_data(&self) -> String { + initial_quill_delta_string() } fn data_type(&self) -> ViewDataType { @@ -169,27 +183,50 @@ impl ViewDataProcessor for BlockManagerViewDataImpl { } struct GridManagerViewDataImpl(Arc); -#[async_trait] impl ViewDataProcessor for GridManagerViewDataImpl { - async fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FlowyResult<()> { - let _ = self.0.create_grid(view_id, repeated_revision).await?; - Ok(()) + fn initialize(&self) -> FutureResult<(), FlowyError> { + FutureResult::new(async { Ok(()) }) } - async fn delete_container(&self, view_id: &str) -> FlowyResult<()> { - let _ = self.0.delete_grid(view_id)?; - Ok(()) + fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FutureResult<(), FlowyError> { + let grid_manager = self.0.clone(); + let view_id = view_id.to_string(); + FutureResult::new(async move { + let _ = grid_manager.create_grid(view_id, repeated_revision).await?; + Ok(()) + }) } - async fn close_container(&self, view_id: &str) -> FlowyResult<()> { - let _ = self.0.close_grid(view_id)?; - Ok(()) + fn delete_container(&self, view_id: &str) -> FutureResult<(), FlowyError> { + let grid_manager = self.0.clone(); + let view_id = view_id.to_string(); + FutureResult::new(async move { + let _ = grid_manager.delete_grid(view_id)?; + Ok(()) + }) } - async fn delta_str(&self, view_id: &str) -> FlowyResult { - let editor = self.0.open_grid(view_id).await?; - let delta_str = editor.delta_str().await; - Ok(delta_str) + fn close_container(&self, view_id: &str) -> FutureResult<(), FlowyError> { + let grid_manager = self.0.clone(); + let view_id = view_id.to_string(); + FutureResult::new(async move { + let _ = grid_manager.close_grid(view_id)?; + Ok(()) + }) + } + + fn delta_str(&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) + }) + } + + fn default_view_data(&self) -> String { + default_grid() } fn data_type(&self) -> ViewDataType { diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/grid_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/grid_deps.rs index 26eb87ecbc..64ad6e9dd4 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/grid_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/grid_deps.rs @@ -17,9 +17,8 @@ pub struct GridDepsResolver(); impl GridDepsResolver { pub fn resolve(ws_conn: Arc, user_session: Arc) -> Arc { let user = Arc::new(GridUserImpl(user_session)); - let rev_web_socket = Arc::new(GridWebSocket(ws_conn.clone())); - let manager = Arc::new(GridManager::new(user, rev_web_socket)); - manager + let rev_web_socket = Arc::new(GridWebSocket(ws_conn)); + Arc::new(GridManager::new(user, rev_web_socket)) } } diff --git a/frontend/rust-lib/flowy-sdk/src/module.rs b/frontend/rust-lib/flowy-sdk/src/module.rs index 17179aa59c..18bf44a2af 100644 --- a/frontend/rust-lib/flowy-sdk/src/module.rs +++ b/frontend/rust-lib/flowy-sdk/src/module.rs @@ -17,7 +17,8 @@ pub fn mk_modules( 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()); - vec![user_module, folder_module, network_module, grid_module] + let block_module = mk_block_module(block_manager.clone()); + vec![user_module, folder_module, network_module, grid_module, block_module] } fn mk_user_module(user_session: Arc) -> Module { 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 0ecefce257..455f12c002 100644 --- a/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_folder/folder_pad.rs @@ -9,7 +9,7 @@ use crate::{ }; use flowy_folder_data_model::entities::{app::App, trash::Trash, view::View, workspace::Workspace}; use lib_ot::core::*; -use lib_ot::rich_text::RichTextAttributes; + use serde::{Deserialize, Serialize}; use std::sync::Arc; 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 0b970d0bfa..51be4dac63 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,9 @@ 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::{CellChangeset, Field, FieldOrder, Grid, RawRow, RepeatedFieldOrder, RowOrder}; +use flowy_grid_data_model::entities::{Field, FieldOrder, Grid, RawRow, RepeatedFieldOrder, RowOrder}; use lib_infra::uuid; -use lib_ot::core::{FlowyStr, OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; +use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use std::sync::Arc; pub type GridDelta = PlainTextDelta; @@ -54,7 +54,7 @@ impl GridPad { }) } - pub fn delete_rows(&mut self, row_ids: &Vec) -> CollaborateResult> { + 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)); Ok(Some(())) @@ -99,7 +99,7 @@ impl GridPad { F: FnOnce(&mut Grid) -> CollaborateResult>, { let cloned_grid = self.grid.clone(); - match f(&mut Arc::make_mut(&mut self.grid))? { + match f(Arc::make_mut(&mut self.grid))? { None => Ok(None), Some(_) => { let old = json_from_grid(&cloned_grid)?; 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 7024b054d8..287ffffa6b 100644 --- a/shared-lib/flowy-grid-data-model/tests/serde_test.rs +++ b/shared-lib/flowy-grid-data-model/tests/serde_test.rs @@ -53,6 +53,7 @@ fn create_row_order(grid_id: &str, row_id: &str) -> RowOrder { } } +#[allow(dead_code)] fn uuid() -> String { uuid::Uuid::new_v4().to_string() } From 9bb516786eeb247b5daeaf1cdb4577b98bf0a446 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 6 Mar 2022 11:28:24 +0800 Subject: [PATCH 16/17] fix: make grid with view_id --- .../lib/startup/home_deps_resolver.dart | 10 +++++ .../workspace/application/grid/grid_bloc.dart | 4 +- .../plugins/grid/src/grid_page.dart | 4 +- frontend/rust-lib/flowy-folder/src/manager.rs | 2 +- .../src/services/view/controller.rs | 2 +- .../rust-lib/flowy-grid/src/event_handler.rs | 8 ++-- frontend/rust-lib/flowy-grid/src/manager.rs | 42 ++++++++----------- .../flowy-sdk/src/deps_resolve/folder_deps.rs | 6 +-- frontend/rust-lib/flowy-sdk/src/lib.rs | 5 ++- .../flowy-collaboration/src/synchronizer.rs | 2 +- 10 files changed, 46 insertions(+), 39 deletions(-) diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart index c006c9de88..f8c8d60e8f 100644 --- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/home_deps_resolver.dart @@ -7,6 +7,8 @@ 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'; @@ -97,6 +99,14 @@ class HomeDepsResolver { ), ); + // Grid + getIt.registerFactoryParam( + (view, _) => GridBloc( + view: view, + service: GridService(), + ), + ); + // trash getIt.registerLazySingleton(() => TrashService()); getIt.registerLazySingleton(() => TrashListener()); 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 f858113fcc..b915435343 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 @@ part 'grid_bloc.freezed.dart'; class GridBloc extends Bloc { final GridService service; final View view; - late Grid? _grid; - late List? _fields; + Grid? _grid; + List? _fields; GridBloc({required this.view, required this.service}) : super(GridState.initial()) { on( 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 33b8c94fa5..e53a2f01e2 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 @@ -31,7 +31,9 @@ class _GridPageState extends State { Widget build(BuildContext context) { return MultiBlocProvider( providers: [ - BlocProvider(create: (context) => getIt()), + BlocProvider( + create: (context) => getIt(param1: widget.view)..add(const GridEvent.initial()), + ), ], child: BlocBuilder( builder: (context, state) { diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 713ab9e3b3..db81ca3144 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -241,7 +241,7 @@ pub trait ViewDataProcessor { fn delta_str(&self, view_id: &str) -> FutureResult; - fn default_view_data(&self) -> String; + fn default_view_data(&self, view_id: &str) -> String; fn data_type(&self) -> ViewDataType; } 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 455bd78c44..5412f7d0b6 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -59,7 +59,7 @@ impl ViewController { 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(); + let default_view_data = processor.default_view_data(¶ms.view_id); params.data = default_view_data.clone(); default_view_data } else { diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 72e2272c03..26e871db05 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -4,7 +4,7 @@ use flowy_grid_data_model::entities::{Grid, GridId, QueryFieldPayload, QueryRowP use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; -#[tracing::instrument(skip(data, manager), err)] +#[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn open_grid_handler( data: Data, manager: AppData>, @@ -15,7 +15,7 @@ pub(crate) async fn open_grid_handler( data_result(grid) } -#[tracing::instrument(skip(data, manager), err)] +#[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn get_rows_handler( data: Data, manager: AppData>, @@ -26,7 +26,7 @@ pub(crate) async fn get_rows_handler( data_result(repeated_row) } -#[tracing::instrument(skip(data, manager), err)] +#[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn get_fields_handler( data: Data, manager: AppData>, @@ -37,7 +37,7 @@ pub(crate) async fn get_fields_handler( data_result(repeated_field) } -#[tracing::instrument(skip(data, manager), err)] +#[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn create_row_handler( data: Data, manager: AppData>, diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 17acaad3fa..c55507e59f 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -17,20 +17,20 @@ pub trait GridUser: Send + Sync { } pub struct GridManager { - grid_editors: Arc, + editor_map: Arc, grid_user: Arc, kv_persistence: Arc>>>, } impl GridManager { pub fn new(grid_user: Arc, _rev_web_socket: Arc) -> Self { - let grid_editors = Arc::new(GridEditors::new()); + let grid_editors = Arc::new(GridEditorMap::new()); // kv_persistence will be initialized after first access. // See get_kv_persistence function below let kv_persistence = Arc::new(RwLock::new(None)); Self { - grid_editors, + editor_map: grid_editors, grid_user, kv_persistence, } @@ -56,7 +56,7 @@ impl GridManager { pub fn close_grid>(&self, grid_id: T) -> FlowyResult<()> { let grid_id = grid_id.as_ref(); tracing::Span::current().record("grid_id", &grid_id); - self.grid_editors.remove(grid_id); + self.editor_map.remove(grid_id); Ok(()) } @@ -64,22 +64,26 @@ impl GridManager { pub fn delete_grid>(&self, grid_id: T) -> FlowyResult<()> { let grid_id = grid_id.as_ref(); tracing::Span::current().record("grid_id", &grid_id); - self.grid_editors.remove(grid_id); + self.editor_map.remove(grid_id); Ok(()) } + #[tracing::instrument(level = "debug", skip(self), err)] pub fn get_grid_editor(&self, grid_id: &str) -> FlowyResult> { - match self.grid_editors.get(grid_id) { + match self.editor_map.get(grid_id) { None => Err(FlowyError::internal().context("Should call open_grid function first")), Some(editor) => Ok(editor), } } async fn get_or_create_grid_editor(&self, grid_id: &str) -> FlowyResult> { - match self.grid_editors.get(grid_id) { + match self.editor_map.get(grid_id) { None => { + tracing::trace!("Create grid editor with id: {}", grid_id); let db_pool = self.grid_user.db_pool()?; - self.make_grid_editor(grid_id, db_pool).await + let editor = self.make_grid_editor(grid_id, db_pool).await?; + self.editor_map.insert(grid_id, &editor); + Ok(editor) } Some(editor) => Ok(editor), } @@ -94,7 +98,6 @@ impl GridManager { 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?; - self.grid_editors.insert(grid_id, &grid_editor); Ok(grid_editor) } @@ -120,8 +123,7 @@ impl GridManager { } use lib_infra::uuid; -pub fn default_grid() -> String { - let grid_id = uuid(); +pub fn default_grid(grid_id: &str) -> String { let fields = vec![ Field { id: uuid(), @@ -146,12 +148,12 @@ pub fn default_grid() -> String { let rows = vec![ RawRow { id: uuid(), - grid_id: grid_id.clone(), + grid_id: grid_id.to_string(), cell_by_field_id: Default::default(), }, RawRow { id: uuid(), - grid_id: grid_id.clone(), + grid_id: grid_id.to_string(), cell_by_field_id: Default::default(), }, ]; @@ -172,11 +174,11 @@ pub fn make_grid(grid_id: &str, fields: Vec, rows: Vec) -> String delta.to_delta_str() } -pub struct GridEditors { +pub struct GridEditorMap { inner: DashMap>, } -impl GridEditors { +impl GridEditorMap { fn new() -> Self { Self { inner: DashMap::new() } } @@ -188,16 +190,8 @@ impl GridEditors { self.inner.insert(grid_id.to_string(), grid_editor.clone()); } - pub(crate) fn contains(&self, grid_id: &str) -> bool { - self.inner.get(grid_id).is_some() - } - pub(crate) fn get(&self, grid_id: &str) -> Option> { - if !self.contains(grid_id) { - return None; - } - let opened_grid = self.inner.get(grid_id).unwrap(); - Some(opened_grid.clone()) + Some(self.inner.get(grid_id)?.clone()) } pub(crate) fn remove(&self, grid_id: &str) { 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 fc979937ad..e2148daa31 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 @@ -173,7 +173,7 @@ impl ViewDataProcessor for BlockManagerViewDataImpl { }) } - fn default_view_data(&self) -> String { + fn default_view_data(&self, _view_id: &str) -> String { initial_quill_delta_string() } @@ -225,8 +225,8 @@ impl ViewDataProcessor for GridManagerViewDataImpl { }) } - fn default_view_data(&self) -> String { - default_grid() + fn default_view_data(&self, view_id: &str) -> String { + default_grid(view_id) } fn data_type(&self) -> ViewDataType { diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index bb3b12aa6e..7c254acd66 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -67,7 +67,8 @@ fn crate_log_filter(level: String) -> String { filters.push(format!("flowy_sdk={}", level)); filters.push(format!("flowy_folder={}", level)); filters.push(format!("flowy_user={}", level)); - filters.push(format!("flowy_document={}", level)); + filters.push(format!("flowy_block={}", level)); + filters.push(format!("flowy_grid={}", level)); filters.push(format!("flowy_collaboration={}", "debug")); filters.push(format!("dart_notify={}", level)); filters.push(format!("lib_ot={}", level)); @@ -78,7 +79,7 @@ fn crate_log_filter(level: String) -> String { filters.push(format!("flowy_database={}", "info")); filters.push(format!("flowy_net={}", "info")); filters.push(format!("flowy_sync={}", "info")); - filters.push(format!("flowy_sync={}", "info")); + filters.join(",") } diff --git a/shared-lib/flowy-collaboration/src/synchronizer.rs b/shared-lib/flowy-collaboration/src/synchronizer.rs index 2141b84952..1305c471b2 100644 --- a/shared-lib/flowy-collaboration/src/synchronizer.rs +++ b/shared-lib/flowy-collaboration/src/synchronizer.rs @@ -83,7 +83,7 @@ where } } - #[tracing::instrument(level = "debug", skip(self, user, repeated_revision), err)] + #[tracing::instrument(level = "trace", skip(self, user, repeated_revision), err)] pub async fn sync_revisions( &self, user: Arc, From 05441f865ed616083c5a0e264f40dfb64a3f9502 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 6 Mar 2022 21:22:42 +0800 Subject: [PATCH 17/17] feat: show grid --- frontend/app_flowy/lib/plugin/plugin.dart | 2 +- .../workspace/application/doc/doc_bloc.dart | 2 +- .../application/doc/doc_service.dart | 13 ++- .../application/grid/grid_service.dart | 7 +- .../presentation/plugins/doc/document.dart | 2 +- .../presentation/plugins/grid/grid.dart | 2 +- .../dart_event/flowy-block/dart_event.dart | 25 ++++- .../dart_event/flowy-folder/dart_event.dart | 10 +- .../dart_event/flowy-grid/dart_event.dart | 6 +- .../flowy-block/event_map.pbenum.dart | 8 +- .../flowy-block/event_map.pbjson.dart | 7 +- .../flowy-folder-data-model/view.pb.dart | 6 +- .../flowy-folder-data-model/view.pbenum.dart | 8 +- .../flowy-folder-data-model/view.pbjson.dart | 7 +- .../flowy-folder/event_map.pbenum.dart | 4 +- .../flowy-folder/event_map.pbjson.dart | 4 +- .../protobuf/flowy-grid/event_map.pbenum.dart | 4 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 4 +- frontend/rust-lib/dart-ffi/Cargo.toml | 4 +- .../rust-lib/flowy-block/src/event_handler.rs | 15 ++- .../rust-lib/flowy-block/src/event_map.rs | 10 +- .../src/protobuf/model/event_map.rs | 20 ++-- .../src/protobuf/proto/event_map.proto | 5 +- .../rust-lib/flowy-folder/src/event_map.rs | 6 +- frontend/rust-lib/flowy-folder/src/manager.rs | 4 +- .../src/protobuf/model/event_map.rs | 20 ++-- .../src/protobuf/proto/event_map.proto | 2 +- .../persistence/version_1/view_sql.rs | 22 ++-- .../src/services/view/controller.rs | 15 +-- .../src/services/view/event_handler.rs | 9 +- .../flowy-folder/tests/workspace/helper.rs | 2 +- .../flowy-folder/tests/workspace/script.rs | 4 +- .../rust-lib/flowy-grid/src/event_handler.rs | 2 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 4 +- frontend/rust-lib/flowy-grid/src/lib.rs | 2 +- frontend/rust-lib/flowy-grid/src/manager.rs | 71 +++--------- .../src/protobuf/model/event_map.rs | 14 +-- .../src/protobuf/proto/event_map.proto | 2 +- .../flowy-grid/src/services/cell_data.rs | 4 +- .../flowy-grid/src/services/grid_builder.rs | 106 ++++++++++++++++++ .../rust-lib/flowy-grid/src/services/mod.rs | 1 + .../rust-lib/flowy-grid/src/services/util.rs | 2 +- .../flowy-sdk/src/deps_resolve/folder_deps.rs | 7 +- frontend/rust-lib/flowy-test/src/helper.rs | 2 +- .../src/entities/document_info.rs | 19 +++- .../src/entities/view.rs | 14 +-- .../src/protobuf/model/view.rs | 44 ++++---- .../src/protobuf/proto/view.proto | 5 +- .../src/user_default.rs | 2 +- 49 files changed, 330 insertions(+), 230 deletions(-) create mode 100644 frontend/rust-lib/flowy-grid/src/services/grid_builder.rs diff --git a/frontend/app_flowy/lib/plugin/plugin.dart b/frontend/app_flowy/lib/plugin/plugin.dart index c9f7d2abd1..58b428cb94 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.PlainText; + ViewDataType get dataType => ViewDataType.Block; } abstract class PluginConfig { diff --git a/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart b/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart index d08b108f15..1f746ffec0 100644 --- a/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart @@ -85,7 +85,7 @@ class DocumentBloc extends Bloc { }); listener.start(); - final result = await service.openDocument(docId: view.id, dataType: view.dataType); + final result = await service.openDocument(docId: view.id); result.fold( (block) { document = _decodeJsonToDocument(block.deltaStr); diff --git a/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart b/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart index e107dda5ee..8cda1bb087 100644 --- a/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart +++ b/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart @@ -7,17 +7,18 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; class DocumentService { Future> openDocument({ required String docId, - required ViewDataType dataType, - }) { - final request = ViewId(value: docId); - return FolderEventOpenView(request).send(); + }) async { + await FolderEventSetLatestView(ViewId(value: docId)).send(); + + final payload = BlockId(value: docId); + return BlockEventGetBlockData(payload).send(); } Future> composeDelta({required String docId, required String data}) { - final request = BlockDelta.create() + final payload = BlockDelta.create() ..blockId = docId ..deltaStr = data; - return FolderEventApplyDocDelta(request).send(); + return FolderEventApplyDocDelta(payload).send(); } Future> closeDocument({required String docId}) { 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 5f0cda7813..5f7f56fb45 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -1,12 +1,15 @@ import 'package:flowy_sdk/dispatch/dispatch.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/grid.pb.dart'; import 'package:dartz/dartz.dart'; class GridService { - Future> openGrid({required String gridId}) { + Future> openGrid({required String gridId}) async { + await FolderEventSetLatestView(ViewId(value: gridId)).send(); + final payload = GridId(value: gridId); - return GridEventOpenGrid(payload).send(); + return GridEventGetGridData(payload).send(); } Future> createRow({required String gridId}) { 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 cf09edfc31..53e0bf58aa 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.RichText; + ViewDataType get dataType => ViewDataType.Block; } class DocumentPlugin implements Plugin { 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 0aa7237a7d..b73970508c 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/grid.dart @@ -17,7 +17,7 @@ class GridPluginBuilder implements PluginBuilder { } @override - String get menuName => "Table"; + String get menuName => "Grid"; @override PluginType get pluginType => DefaultPlugin.grid.type(); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-block/dart_event.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-block/dart_event.dart index f14e33f7cc..052905e8c5 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-block/dart_event.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-block/dart_event.dart @@ -1,13 +1,30 @@ /// Auto generate. Do not edit part of '../../dispatch.dart'; -class BlockEventApplyDocDelta { - BlockDelta request; - BlockEventApplyDocDelta(this.request); +class BlockEventGetBlockData { + BlockId request; + BlockEventGetBlockData(this.request); Future> send() { final request = FFIRequest.create() - ..event = BlockEvent.ApplyDocDelta.toString() + ..event = BlockEvent.GetBlockData.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (okBytes) => left(BlockDelta.fromBuffer(okBytes)), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + +class BlockEventApplyDelta { + BlockDelta request; + BlockEventApplyDelta(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = BlockEvent.ApplyDelta.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-folder/dart_event.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-folder/dart_event.dart index 99d6d56d89..27986fc1c8 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-folder/dart_event.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-folder/dart_event.dart @@ -267,18 +267,18 @@ class FolderEventCopyLink { } } -class FolderEventOpenView { +class FolderEventSetLatestView { ViewId request; - FolderEventOpenView(this.request); + FolderEventSetLatestView(this.request); - Future> send() { + Future> send() { final request = FFIRequest.create() - ..event = FolderEvent.OpenView.toString() + ..event = FolderEvent.SetLatestView.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) .then((bytesResult) => bytesResult.fold( - (okBytes) => left(BlockDelta.fromBuffer(okBytes)), + (bytes) => left(unit), (errBytes) => right(FlowyError.fromBuffer(errBytes)), )); } 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 d7543eb486..b62b350f5e 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 @@ -1,13 +1,13 @@ /// Auto generate. Do not edit part of '../../dispatch.dart'; -class GridEventOpenGrid { +class GridEventGetGridData { GridId request; - GridEventOpenGrid(this.request); + GridEventGetGridData(this.request); Future> send() { final request = FFIRequest.create() - ..event = GridEvent.OpenGrid.toString() + ..event = GridEvent.GetGridData.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbenum.dart index 599e220c77..d88c52395c 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbenum.dart @@ -10,11 +10,13 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; class BlockEvent extends $pb.ProtobufEnum { - static const BlockEvent ApplyDocDelta = BlockEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplyDocDelta'); - static const BlockEvent ExportDocument = BlockEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ExportDocument'); + static const BlockEvent GetBlockData = BlockEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetBlockData'); + static const BlockEvent ApplyDelta = BlockEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplyDelta'); + static const BlockEvent ExportDocument = BlockEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ExportDocument'); static const $core.List values = [ - ApplyDocDelta, + GetBlockData, + ApplyDelta, ExportDocument, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbjson.dart index 7ff062a62a..ac0f243e6f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-block/event_map.pbjson.dart @@ -12,10 +12,11 @@ import 'dart:typed_data' as $typed_data; const BlockEvent$json = const { '1': 'BlockEvent', '2': const [ - const {'1': 'ApplyDocDelta', '2': 0}, - const {'1': 'ExportDocument', '2': 1}, + const {'1': 'GetBlockData', '2': 0}, + const {'1': 'ApplyDelta', '2': 1}, + const {'1': 'ExportDocument', '2': 2}, ], }; /// Descriptor for `BlockEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List blockEventDescriptor = $convert.base64Decode('CgpCbG9ja0V2ZW50EhEKDUFwcGx5RG9jRGVsdGEQABISCg5FeHBvcnREb2N1bWVudBAB'); +final $typed_data.Uint8List blockEventDescriptor = $convert.base64Decode('CgpCbG9ja0V2ZW50EhAKDEdldEJsb2NrRGF0YRAAEg4KCkFwcGx5RGVsdGEQARISCg5FeHBvcnREb2N1bWVudBAC'); 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 6bf9801803..bc0b49b833 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.RichText, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) + ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.Block, 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.RichText, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) + ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.Block, 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.RichText, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values) + ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.Block, 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 400c1d579a..f644361742 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,13 +10,11 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; class ViewDataType extends $pb.ProtobufEnum { - static const ViewDataType RichText = ViewDataType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RichText'); - static const ViewDataType PlainText = ViewDataType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PlainText'); - static const ViewDataType Grid = ViewDataType._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Grid'); + static const ViewDataType Block = ViewDataType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Block'); + static const ViewDataType Grid = ViewDataType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Grid'); static const $core.List values = [ - RichText, - PlainText, + Block, 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 8cb2913dfe..87ebb89969 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,14 +12,13 @@ import 'dart:typed_data' as $typed_data; const ViewDataType$json = const { '1': 'ViewDataType', '2': const [ - const {'1': 'RichText', '2': 0}, - const {'1': 'PlainText', '2': 1}, - const {'1': 'Grid', '2': 2}, + const {'1': 'Block', '2': 0}, + const {'1': 'Grid', '2': 1}, ], }; /// Descriptor for `ViewDataType`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List viewDataTypeDescriptor = $convert.base64Decode('CgxWaWV3RGF0YVR5cGUSDAoIUmljaFRleHQQABINCglQbGFpblRleHQQARIICgRHcmlkEAI='); +final $typed_data.Uint8List viewDataTypeDescriptor = $convert.base64Decode('CgxWaWV3RGF0YVR5cGUSCQoFQmxvY2sQABIICgRHcmlkEAE='); @$core.Deprecated('Use viewDescriptor instead') const View$json = const { '1': 'View', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart index dd502e087f..5567086c85 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart @@ -26,7 +26,7 @@ class FolderEvent extends $pb.ProtobufEnum { static const FolderEvent DeleteView = FolderEvent._(204, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteView'); static const FolderEvent DuplicateView = FolderEvent._(205, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateView'); static const FolderEvent CopyLink = FolderEvent._(206, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CopyLink'); - static const FolderEvent OpenView = FolderEvent._(207, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'OpenView'); + static const FolderEvent SetLatestView = FolderEvent._(207, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SetLatestView'); static const FolderEvent CloseView = FolderEvent._(208, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CloseView'); static const FolderEvent ReadTrash = FolderEvent._(300, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadTrash'); static const FolderEvent PutbackTrash = FolderEvent._(301, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PutbackTrash'); @@ -53,7 +53,7 @@ class FolderEvent extends $pb.ProtobufEnum { DeleteView, DuplicateView, CopyLink, - OpenView, + SetLatestView, CloseView, ReadTrash, PutbackTrash, diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbjson.dart index e992c85ab7..513dc1611c 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbjson.dart @@ -28,7 +28,7 @@ const FolderEvent$json = const { const {'1': 'DeleteView', '2': 204}, const {'1': 'DuplicateView', '2': 205}, const {'1': 'CopyLink', '2': 206}, - const {'1': 'OpenView', '2': 207}, + const {'1': 'SetLatestView', '2': 207}, const {'1': 'CloseView', '2': 208}, const {'1': 'ReadTrash', '2': 300}, const {'1': 'PutbackTrash', '2': 301}, @@ -41,4 +41,4 @@ const FolderEvent$json = const { }; /// Descriptor for `FolderEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List folderEventDescriptor = $convert.base64Decode('CgtGb2xkZXJFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIUChBSZWFkQ3VyV29ya3NwYWNlEAESEgoOUmVhZFdvcmtzcGFjZXMQAhITCg9EZWxldGVXb3Jrc3BhY2UQAxIRCg1PcGVuV29ya3NwYWNlEAQSFQoRUmVhZFdvcmtzcGFjZUFwcHMQBRINCglDcmVhdGVBcHAQZRINCglEZWxldGVBcHAQZhILCgdSZWFkQXBwEGcSDQoJVXBkYXRlQXBwEGgSDwoKQ3JlYXRlVmlldxDJARINCghSZWFkVmlldxDKARIPCgpVcGRhdGVWaWV3EMsBEg8KCkRlbGV0ZVZpZXcQzAESEgoNRHVwbGljYXRlVmlldxDNARINCghDb3B5TGluaxDOARINCghPcGVuVmlldxDPARIOCglDbG9zZVZpZXcQ0AESDgoJUmVhZFRyYXNoEKwCEhEKDFB1dGJhY2tUcmFzaBCtAhIQCgtEZWxldGVUcmFzaBCuAhIUCg9SZXN0b3JlQWxsVHJhc2gQrwISEwoORGVsZXRlQWxsVHJhc2gQsAISEgoNQXBwbHlEb2NEZWx0YRCQAxITCg5FeHBvcnREb2N1bWVudBD0Aw=='); +final $typed_data.Uint8List folderEventDescriptor = $convert.base64Decode('CgtGb2xkZXJFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIUChBSZWFkQ3VyV29ya3NwYWNlEAESEgoOUmVhZFdvcmtzcGFjZXMQAhITCg9EZWxldGVXb3Jrc3BhY2UQAxIRCg1PcGVuV29ya3NwYWNlEAQSFQoRUmVhZFdvcmtzcGFjZUFwcHMQBRINCglDcmVhdGVBcHAQZRINCglEZWxldGVBcHAQZhILCgdSZWFkQXBwEGcSDQoJVXBkYXRlQXBwEGgSDwoKQ3JlYXRlVmlldxDJARINCghSZWFkVmlldxDKARIPCgpVcGRhdGVWaWV3EMsBEg8KCkRlbGV0ZVZpZXcQzAESEgoNRHVwbGljYXRlVmlldxDNARINCghDb3B5TGluaxDOARISCg1TZXRMYXRlc3RWaWV3EM8BEg4KCUNsb3NlVmlldxDQARIOCglSZWFkVHJhc2gQrAISEQoMUHV0YmFja1RyYXNoEK0CEhAKC0RlbGV0ZVRyYXNoEK4CEhQKD1Jlc3RvcmVBbGxUcmFzaBCvAhITCg5EZWxldGVBbGxUcmFzaBCwAhISCg1BcHBseURvY0RlbHRhEJADEhMKDkV4cG9ydERvY3VtZW50EPQD'); 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 7877beefde..29a15a76b3 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 @@ -10,13 +10,13 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; class GridEvent extends $pb.ProtobufEnum { - static const GridEvent OpenGrid = GridEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'OpenGrid'); + 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 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 $core.List values = [ - OpenGrid, + GetGridData, GetRows, GetFields, CreateRow, 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 96b422a379..0791be4e50 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 @@ -12,7 +12,7 @@ import 'dart:typed_data' as $typed_data; const GridEvent$json = const { '1': 'GridEvent', '2': const [ - const {'1': 'OpenGrid', '2': 0}, + const {'1': 'GetGridData', '2': 0}, const {'1': 'GetRows', '2': 1}, const {'1': 'GetFields', '2': 2}, const {'1': 'CreateRow', '2': 3}, @@ -20,4 +20,4 @@ const GridEvent$json = const { }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDAoIT3BlbkdyaWQQABILCgdHZXRSb3dzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAM='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABILCgdHZXRSb3dzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAM='); 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/event_handler.rs b/frontend/rust-lib/flowy-block/src/event_handler.rs index 1dcf5d4333..39761d3d7c 100644 --- a/frontend/rust-lib/flowy-block/src/event_handler.rs +++ b/frontend/rust-lib/flowy-block/src/event_handler.rs @@ -1,11 +1,24 @@ use crate::entities::{ExportData, ExportParams, ExportPayload}; use crate::BlockManager; -use flowy_collaboration::entities::document_info::BlockDelta; +use flowy_collaboration::entities::document_info::{BlockDelta, BlockId}; 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(); + let editor = manager.open_block(&block_id).await?; + let delta_str = editor.delta_str().await?; + data_result(BlockDelta { + block_id: block_id.into(), + delta_str, + }) +} + pub(crate) async fn apply_delta_handler( data: Data, manager: AppData>, diff --git a/frontend/rust-lib/flowy-block/src/event_map.rs b/frontend/rust-lib/flowy-block/src/event_map.rs index 9997d7ca20..f0cfda219c 100644 --- a/frontend/rust-lib/flowy-block/src/event_map.rs +++ b/frontend/rust-lib/flowy-block/src/event_map.rs @@ -9,7 +9,8 @@ pub fn create(block_manager: Arc) -> Module { let mut module = Module::new().name(env!("CARGO_PKG_NAME")).data(block_manager); module = module - .event(BlockEvent::ApplyDocDelta, apply_delta_handler) + .event(BlockEvent::GetBlockData, get_block_data_handler) + .event(BlockEvent::ApplyDelta, apply_delta_handler) .event(BlockEvent::ExportDocument, export_handler); module @@ -18,9 +19,12 @@ pub fn create(block_manager: Arc) -> Module { #[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] #[event_err = "FlowyError"] pub enum BlockEvent { + #[event(input = "BlockId", output = "BlockDelta")] + GetBlockData = 0, + #[event(input = "BlockDelta", output = "BlockDelta")] - ApplyDocDelta = 0, + ApplyDelta = 1, #[event(input = "ExportPayload", output = "ExportData")] - ExportDocument = 1, + ExportDocument = 2, } diff --git a/frontend/rust-lib/flowy-block/src/protobuf/model/event_map.rs b/frontend/rust-lib/flowy-block/src/protobuf/model/event_map.rs index 3078739cf8..ab1a5da855 100644 --- a/frontend/rust-lib/flowy-block/src/protobuf/model/event_map.rs +++ b/frontend/rust-lib/flowy-block/src/protobuf/model/event_map.rs @@ -25,8 +25,9 @@ #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum BlockEvent { - ApplyDocDelta = 0, - ExportDocument = 1, + GetBlockData = 0, + ApplyDelta = 1, + ExportDocument = 2, } impl ::protobuf::ProtobufEnum for BlockEvent { @@ -36,15 +37,17 @@ impl ::protobuf::ProtobufEnum for BlockEvent { fn from_i32(value: i32) -> ::std::option::Option { match value { - 0 => ::std::option::Option::Some(BlockEvent::ApplyDocDelta), - 1 => ::std::option::Option::Some(BlockEvent::ExportDocument), + 0 => ::std::option::Option::Some(BlockEvent::GetBlockData), + 1 => ::std::option::Option::Some(BlockEvent::ApplyDelta), + 2 => ::std::option::Option::Some(BlockEvent::ExportDocument), _ => ::std::option::Option::None } } fn values() -> &'static [Self] { static values: &'static [BlockEvent] = &[ - BlockEvent::ApplyDocDelta, + BlockEvent::GetBlockData, + BlockEvent::ApplyDelta, BlockEvent::ExportDocument, ]; values @@ -63,7 +66,7 @@ impl ::std::marker::Copy for BlockEvent { impl ::std::default::Default for BlockEvent { fn default() -> Self { - BlockEvent::ApplyDocDelta + BlockEvent::GetBlockData } } @@ -74,8 +77,9 @@ impl ::protobuf::reflect::ProtobufValue for BlockEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*3\n\nBlockEvent\x12\x11\n\rApplyDocDelta\x10\0\x12\ - \x12\n\x0eExportDocument\x10\x01b\x06proto3\ + \n\x0fevent_map.proto*B\n\nBlockEvent\x12\x10\n\x0cGetBlockData\x10\0\ + \x12\x0e\n\nApplyDelta\x10\x01\x12\x12\n\x0eExportDocument\x10\x02b\x06p\ + roto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-block/src/protobuf/proto/event_map.proto b/frontend/rust-lib/flowy-block/src/protobuf/proto/event_map.proto index adc99e6941..3ebf0755d3 100644 --- a/frontend/rust-lib/flowy-block/src/protobuf/proto/event_map.proto +++ b/frontend/rust-lib/flowy-block/src/protobuf/proto/event_map.proto @@ -1,6 +1,7 @@ syntax = "proto3"; enum BlockEvent { - ApplyDocDelta = 0; - ExportDocument = 1; + GetBlockData = 0; + ApplyDelta = 1; + ExportDocument = 2; } diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index 483de91cc3..02e28d4c50 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -63,7 +63,7 @@ pub fn create(folder: Arc) -> Module { .event(FolderEvent::UpdateView, update_view_handler) .event(FolderEvent::DeleteView, delete_view_handler) .event(FolderEvent::DuplicateView, duplicate_view_handler) - .event(FolderEvent::OpenView, open_view_handler) + .event(FolderEvent::SetLatestView, set_latest_view_handler) .event(FolderEvent::CloseView, close_view_handler); module = module @@ -127,8 +127,8 @@ pub enum FolderEvent { #[event()] CopyLink = 206, - #[event(input = "ViewId", output = "BlockDelta")] - OpenView = 207, + #[event(input = "ViewId")] + SetLatestView = 207, #[event(input = "ViewId")] CloseView = 208, diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index db81ca3144..b41539d628 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -206,9 +206,9 @@ impl DefaultFolderBuilder { } else { initial_quill_delta_string() }; - view_controller.set_latest_view(view); + let _ = view_controller.set_latest_view(&view.id); let _ = view_controller - .create_view(&view.id, ViewDataType::RichText, Bytes::from(view_data)) + .create_view(&view.id, ViewDataType::Block, Bytes::from(view_data)) .await?; } } diff --git a/frontend/rust-lib/flowy-folder/src/protobuf/model/event_map.rs b/frontend/rust-lib/flowy-folder/src/protobuf/model/event_map.rs index 58606cda0d..6552c3b30f 100644 --- a/frontend/rust-lib/flowy-folder/src/protobuf/model/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/protobuf/model/event_map.rs @@ -41,7 +41,7 @@ pub enum FolderEvent { DeleteView = 204, DuplicateView = 205, CopyLink = 206, - OpenView = 207, + SetLatestView = 207, CloseView = 208, ReadTrash = 300, PutbackTrash = 301, @@ -75,7 +75,7 @@ impl ::protobuf::ProtobufEnum for FolderEvent { 204 => ::std::option::Option::Some(FolderEvent::DeleteView), 205 => ::std::option::Option::Some(FolderEvent::DuplicateView), 206 => ::std::option::Option::Some(FolderEvent::CopyLink), - 207 => ::std::option::Option::Some(FolderEvent::OpenView), + 207 => ::std::option::Option::Some(FolderEvent::SetLatestView), 208 => ::std::option::Option::Some(FolderEvent::CloseView), 300 => ::std::option::Option::Some(FolderEvent::ReadTrash), 301 => ::std::option::Option::Some(FolderEvent::PutbackTrash), @@ -106,7 +106,7 @@ impl ::protobuf::ProtobufEnum for FolderEvent { FolderEvent::DeleteView, FolderEvent::DuplicateView, FolderEvent::CopyLink, - FolderEvent::OpenView, + FolderEvent::SetLatestView, FolderEvent::CloseView, FolderEvent::ReadTrash, FolderEvent::PutbackTrash, @@ -143,19 +143,19 @@ impl ::protobuf::reflect::ProtobufValue for FolderEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xd2\x03\n\x0bFolderEvent\x12\x13\n\x0fCreateWorks\ + \n\x0fevent_map.proto*\xd7\x03\n\x0bFolderEvent\x12\x13\n\x0fCreateWorks\ pace\x10\0\x12\x14\n\x10ReadCurWorkspace\x10\x01\x12\x12\n\x0eReadWorksp\ aces\x10\x02\x12\x13\n\x0fDeleteWorkspace\x10\x03\x12\x11\n\rOpenWorkspa\ ce\x10\x04\x12\x15\n\x11ReadWorkspaceApps\x10\x05\x12\r\n\tCreateApp\x10\ e\x12\r\n\tDeleteApp\x10f\x12\x0b\n\x07ReadApp\x10g\x12\r\n\tUpdateApp\ \x10h\x12\x0f\n\nCreateView\x10\xc9\x01\x12\r\n\x08ReadView\x10\xca\x01\ \x12\x0f\n\nUpdateView\x10\xcb\x01\x12\x0f\n\nDeleteView\x10\xcc\x01\x12\ - \x12\n\rDuplicateView\x10\xcd\x01\x12\r\n\x08CopyLink\x10\xce\x01\x12\r\ - \n\x08OpenView\x10\xcf\x01\x12\x0e\n\tCloseView\x10\xd0\x01\x12\x0e\n\tR\ - eadTrash\x10\xac\x02\x12\x11\n\x0cPutbackTrash\x10\xad\x02\x12\x10\n\x0b\ - DeleteTrash\x10\xae\x02\x12\x14\n\x0fRestoreAllTrash\x10\xaf\x02\x12\x13\ - \n\x0eDeleteAllTrash\x10\xb0\x02\x12\x12\n\rApplyDocDelta\x10\x90\x03\ - \x12\x13\n\x0eExportDocument\x10\xf4\x03b\x06proto3\ + \x12\n\rDuplicateView\x10\xcd\x01\x12\r\n\x08CopyLink\x10\xce\x01\x12\ + \x12\n\rSetLatestView\x10\xcf\x01\x12\x0e\n\tCloseView\x10\xd0\x01\x12\ + \x0e\n\tReadTrash\x10\xac\x02\x12\x11\n\x0cPutbackTrash\x10\xad\x02\x12\ + \x10\n\x0bDeleteTrash\x10\xae\x02\x12\x14\n\x0fRestoreAllTrash\x10\xaf\ + \x02\x12\x13\n\x0eDeleteAllTrash\x10\xb0\x02\x12\x12\n\rApplyDocDelta\ + \x10\x90\x03\x12\x13\n\x0eExportDocument\x10\xf4\x03b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-folder/src/protobuf/proto/event_map.proto b/frontend/rust-lib/flowy-folder/src/protobuf/proto/event_map.proto index a21f0f92c7..9c7d32f3e1 100644 --- a/frontend/rust-lib/flowy-folder/src/protobuf/proto/event_map.proto +++ b/frontend/rust-lib/flowy-folder/src/protobuf/proto/event_map.proto @@ -17,7 +17,7 @@ enum FolderEvent { DeleteView = 204; DuplicateView = 205; CopyLink = 206; - OpenView = 207; + SetLatestView = 207; CloseView = 208; ReadTrash = 300; PutbackTrash = 301; 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 d87b761a7f..c854021b80 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,8 +84,7 @@ pub(crate) struct ViewTable { impl ViewTable { pub fn new(view: View) -> Self { let data_type = match view.data_type { - ViewDataType::RichText => SqlViewDataType::RichText, - ViewDataType::PlainText => SqlViewDataType::PlainText, + ViewDataType::Block => SqlViewDataType::Block, ViewDataType::Grid => SqlViewDataType::Grid, }; @@ -107,8 +106,7 @@ impl ViewTable { impl std::convert::From for View { fn from(table: ViewTable) -> Self { let data_type = match table.view_type { - SqlViewDataType::RichText => ViewDataType::RichText, - SqlViewDataType::PlainText => ViewDataType::PlainText, + SqlViewDataType::Block => ViewDataType::Block, SqlViewDataType::Grid => ViewDataType::Grid, }; @@ -179,26 +177,24 @@ impl ViewChangeset { #[repr(i32)] #[sql_type = "Integer"] pub enum SqlViewDataType { - RichText = 0, - PlainText = 1, - Grid = 2, + Block = 0, + Grid = 1, } impl std::default::Default for SqlViewDataType { fn default() -> Self { - SqlViewDataType::RichText + SqlViewDataType::Block } } impl std::convert::From for SqlViewDataType { fn from(value: i32) -> Self { match value { - 0 => SqlViewDataType::RichText, - 1 => SqlViewDataType::PlainText, - 2 => SqlViewDataType::Grid, + 0 => SqlViewDataType::Block, + 1 => SqlViewDataType::Grid, o => { - log::error!("Unsupported view type {}, fallback to ViewType::Docs", o); - SqlViewDataType::PlainText + log::error!("Unsupported view type {}, fallback to ViewType::Block", o); + SqlViewDataType::Block } } } 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 5412f7d0b6..f09fad218d 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -14,7 +14,7 @@ use crate::{ }; use bytes::Bytes; use flowy_collaboration::entities::{ - document_info::{BlockDelta, BlockId}, + document_info::BlockId, revision::{RepeatedRevision, Revision}, }; use flowy_database::kv::KV; @@ -134,14 +134,9 @@ impl ViewController { } #[tracing::instrument(level = "debug", skip(self), err)] - pub(crate) async fn open_view(&self, view_id: &str) -> Result { - let processor = self.get_data_processor_from_view_id(view_id).await?; - let delta_str = processor.delta_str(view_id).await?; + pub(crate) fn set_latest_view(&self, view_id: &str) -> Result<(), FlowyError> { KV::set_str(LATEST_VIEW_ID, view_id.to_owned()); - Ok(BlockDelta { - block_id: view_id.to_string(), - delta_str, - }) + Ok(()) } #[tracing::instrument(level = "debug", skip(self), err)] @@ -231,10 +226,6 @@ impl ViewController { } } } - - pub(crate) fn set_latest_view(&self, view: &View) { - KV::set_str(LATEST_VIEW_ID, view.id.clone()); - } } impl ViewController { diff --git a/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs b/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs index bde232623d..3468fd62a2 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs @@ -8,7 +8,6 @@ use crate::{ errors::FlowyError, services::{TrashController, ViewController}, }; -use flowy_collaboration::entities::document_info::BlockDelta; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::{convert::TryInto, sync::Arc}; @@ -66,13 +65,13 @@ pub(crate) async fn delete_view_handler( Ok(()) } -pub(crate) async fn open_view_handler( +pub(crate) async fn set_latest_view_handler( data: Data, controller: AppData>, -) -> DataResult { +) -> Result<(), FlowyError> { let view_id: ViewId = data.into_inner(); - let doc = controller.open_view(&view_id.value).await?; - data_result(doc) + let _ = controller.set_latest_view(&view_id.value)?; + Ok(()) } pub(crate) async fn close_view_handler( diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs b/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs index 7d823749df..f0e1107535 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/helper.rs @@ -164,7 +164,7 @@ pub async fn delete_view(sdk: &FlowySDKTest, view_ids: Vec) { pub async fn open_document(sdk: &FlowySDKTest, view_id: &str) -> BlockInfo { let view_id: ViewId = view_id.into(); FolderEventBuilder::new(sdk.clone()) - .event(OpenView) + .event(SetLatestView) .payload(view_id) .async_send() .await diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index d4f0fe0fd8..bc3418f441 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs @@ -68,7 +68,7 @@ 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::RichText).await; + let view = create_view(&sdk, &app.id, "Folder View", "Folder test view", ViewDataType::Block).await; app.belongings = RepeatedView { items: vec![view.clone()], }; @@ -146,7 +146,7 @@ impl FolderTest { } FolderScript::CreateView { name, desc } => { - let view = create_view(sdk, &self.app.id, &name, &desc, ViewDataType::RichText).await; + let view = create_view(sdk, &self.app.id, &name, &desc, ViewDataType::Block).await; self.view = view; } FolderScript::AssertView(view) => { diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 26e871db05..eb17b1f35e 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -5,7 +5,7 @@ use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; #[tracing::instrument(level = "debug", skip(data, manager), err)] -pub(crate) async fn open_grid_handler( +pub(crate) async fn get_grid_data_handler( data: Data, manager: AppData>, ) -> DataResult { diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index a5f6c7fe47..f171e27826 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -8,7 +8,7 @@ use strum_macros::Display; pub fn create(grid_manager: Arc) -> Module { let mut module = Module::new().name(env!("CARGO_PKG_NAME")).data(grid_manager); module = module - .event(GridEvent::OpenGrid, open_grid_handler) + .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); @@ -20,7 +20,7 @@ pub fn create(grid_manager: Arc) -> Module { #[event_err = "FlowyError"] pub enum GridEvent { #[event(input = "GridId", output = "Grid")] - OpenGrid = 0, + GetGridData = 0, #[event(input = "QueryRowPayload", output = "RepeatedRow")] GetRows = 1, diff --git a/frontend/rust-lib/flowy-grid/src/lib.rs b/frontend/rust-lib/flowy-grid/src/lib.rs index a7b1a080e7..262fe1d1c2 100644 --- a/frontend/rust-lib/flowy-grid/src/lib.rs +++ b/frontend/rust-lib/flowy-grid/src/lib.rs @@ -6,4 +6,4 @@ pub mod event_map; pub mod manager; mod protobuf; -mod services; +pub mod services; diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index c55507e59f..95eea5b9cc 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -1,11 +1,12 @@ use crate::services::grid_editor::ClientGridEditor; -use crate::services::kv_persistence::GridKVPersistence; +use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use dashmap::DashMap; -use flowy_collaboration::client_grid::make_grid_delta; + use flowy_collaboration::entities::revision::RepeatedRevision; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{Field, FieldOrder, FieldType, Grid, RawRow, RowOrder}; +use flowy_grid_data_model::entities::{Field, RawRow}; use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; + use lib_sqlite::ConnectionPool; use parking_lot::RwLock; use std::sync::Arc; @@ -76,6 +77,18 @@ 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 => { @@ -122,58 +135,6 @@ impl GridManager { } } -use lib_infra::uuid; -pub fn default_grid(grid_id: &str) -> String { - let fields = vec![ - Field { - id: uuid(), - name: "".to_string(), - desc: "".to_string(), - field_type: FieldType::RichText, - frozen: false, - width: 100, - type_options: Default::default(), - }, - Field { - id: uuid(), - name: "".to_string(), - desc: "".to_string(), - field_type: FieldType::RichText, - frozen: false, - width: 100, - type_options: Default::default(), - }, - ]; - - let rows = vec![ - RawRow { - id: uuid(), - grid_id: grid_id.to_string(), - cell_by_field_id: Default::default(), - }, - RawRow { - id: uuid(), - grid_id: grid_id.to_string(), - cell_by_field_id: Default::default(), - }, - ]; - - make_grid(&grid_id, fields, rows) -} - -pub fn make_grid(grid_id: &str, fields: Vec, rows: Vec) -> String { - let field_orders = fields.iter().map(FieldOrder::from).collect::>(); - let row_orders = rows.iter().map(RowOrder::from).collect::>(); - - let grid = Grid { - id: grid_id.to_owned(), - field_orders: field_orders.into(), - row_orders: row_orders.into(), - }; - let delta = make_grid_delta(&grid); - delta.to_delta_str() -} - pub struct GridEditorMap { inner: DashMap>, } 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 ec00eaf71c..6884312f38 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 @@ -25,7 +25,7 @@ #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum GridEvent { - OpenGrid = 0, + GetGridData = 0, GetRows = 1, GetFields = 2, CreateRow = 3, @@ -38,7 +38,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { fn from_i32(value: i32) -> ::std::option::Option { match value { - 0 => ::std::option::Option::Some(GridEvent::OpenGrid), + 0 => ::std::option::Option::Some(GridEvent::GetGridData), 1 => ::std::option::Option::Some(GridEvent::GetRows), 2 => ::std::option::Option::Some(GridEvent::GetFields), 3 => ::std::option::Option::Some(GridEvent::CreateRow), @@ -48,7 +48,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { fn values() -> &'static [Self] { static values: &'static [GridEvent] = &[ - GridEvent::OpenGrid, + GridEvent::GetGridData, GridEvent::GetRows, GridEvent::GetFields, GridEvent::CreateRow, @@ -69,7 +69,7 @@ impl ::std::marker::Copy for GridEvent { impl ::std::default::Default for GridEvent { fn default() -> Self { - GridEvent::OpenGrid + GridEvent::GetGridData } } @@ -80,9 +80,9 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*D\n\tGridEvent\x12\x0c\n\x08OpenGrid\x10\0\x12\x0b\ - \n\x07GetRows\x10\x01\x12\r\n\tGetFields\x10\x02\x12\r\n\tCreateRow\x10\ - \x03b\x06proto3\ + \n\x0fevent_map.proto*G\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\ "; 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 d0b33de419..0f5de19e98 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 @@ -1,7 +1,7 @@ syntax = "proto3"; enum GridEvent { - OpenGrid = 0; + GetGridData = 0; GetRows = 1; GetFields = 2; CreateRow = 3; diff --git a/frontend/rust-lib/flowy-grid/src/services/cell_data.rs b/frontend/rust-lib/flowy-grid/src/services/cell_data.rs index 64e4b374d2..ce65fb005a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell_data.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell_data.rs @@ -414,7 +414,7 @@ impl std::default::Default for FlowyMoney { impl FlowyMoney { // Currency list https://docs.rs/rusty-money/0.4.0/rusty_money/iso/index.html - pub fn from_str(s: &str) -> FlowyMoney { + pub fn from_symbol_str(s: &str) -> FlowyMoney { match s { "CNY" => FlowyMoney::CNY, "EUR" => FlowyMoney::EUR, @@ -424,7 +424,7 @@ impl FlowyMoney { } pub fn from_money(money: &rusty_money::Money) -> FlowyMoney { - FlowyMoney::from_str(&money.currency().symbol.to_string()) + FlowyMoney::from_symbol_str(&money.currency().symbol.to_string()) } pub fn currency(&self) -> &'static Currency { diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs new file mode 100644 index 0000000000..e67d9176cd --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/grid_builder.rs @@ -0,0 +1,106 @@ +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 lib_infra::uuid; +use std::collections::HashMap; +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 { + id: uuid(), + name: name.to_string(), + desc: desc.to_string(), + field_type, + frozen: false, + width: 100, + type_options: Default::default(), + }; + 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(), + }; + 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, + }; + 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 _ = 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); + Ok(delta.to_delta_str()) + } +} + +#[allow(dead_code)] +fn check_rows(fields: &[Field], rows: &[RawRow]) -> 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/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index dc96f8af5b..f1e1086589 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -1,6 +1,7 @@ mod util; pub mod cell_data; +pub mod grid_builder; pub mod grid_editor; pub mod kv_persistence; pub mod stringify; diff --git a/frontend/rust-lib/flowy-grid/src/services/util.rs b/frontend/rust-lib/flowy-grid/src/services/util.rs index 5ed96fc811..8fa196956d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/util.rs +++ b/frontend/rust-lib/flowy-grid/src/services/util.rs @@ -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_str("CNY").currency(); + let default_currency = FlowyMoney::from_symbol_str("CNY").currency(); if process_money_str.is_empty() { return 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 e2148daa31..e648bd9e66 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 @@ -11,7 +11,8 @@ use flowy_folder::{ event_map::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser}, manager::FolderManager, }; -use flowy_grid::manager::{default_grid, GridManager}; +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, @@ -178,7 +179,7 @@ impl ViewDataProcessor for BlockManagerViewDataImpl { } fn data_type(&self) -> ViewDataType { - ViewDataType::RichText + ViewDataType::Block } } @@ -226,7 +227,7 @@ impl ViewDataProcessor for GridManagerViewDataImpl { } fn default_view_data(&self, view_id: &str) -> String { - default_grid(view_id) + make_default_grid(view_id, self.0.clone()) } fn data_type(&self) -> ViewDataType { diff --git a/frontend/rust-lib/flowy-test/src/helper.rs b/frontend/rust-lib/flowy-test/src/helper.rs index 7d2fc0459d..f28f7d35b0 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::RichText, + data_type: ViewDataType::Block, ext_data: "".to_string(), plugin_type: 0, }; diff --git a/shared-lib/flowy-collaboration/src/entities/document_info.rs b/shared-lib/flowy-collaboration/src/entities/document_info.rs index e0701e3d56..f80ab97207 100644 --- a/shared-lib/flowy-collaboration/src/entities/document_info.rs +++ b/shared-lib/flowy-collaboration/src/entities/document_info.rs @@ -92,6 +92,11 @@ pub struct BlockId { #[pb(index = 1)] pub value: String, } +impl AsRef for BlockId { + fn as_ref(&self) -> &str { + &self.value + } +} impl std::convert::From for BlockId { fn from(value: String) -> Self { @@ -99,10 +104,14 @@ impl std::convert::From for BlockId { } } -impl std::convert::From<&String> for BlockId { - fn from(doc_id: &String) -> Self { - BlockId { - value: doc_id.to_owned(), - } +impl std::convert::From for String { + fn from(block_id: BlockId) -> Self { + block_id.value + } +} + +impl std::convert::From<&String> for BlockId { + fn from(s: &String) -> Self { + BlockId { value: s.to_owned() } } } 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 87065659b6..307850d396 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/view.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/view.rs @@ -83,26 +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 { - RichText = 0, - PlainText = 1, - Grid = 2, + Block = 0, + Grid = 1, } impl std::default::Default for ViewDataType { fn default() -> Self { - ViewDataType::RichText + ViewDataType::Block } } impl std::convert::From for ViewDataType { fn from(val: i32) -> Self { match val { - 0 => ViewDataType::RichText, - 1 => ViewDataType::PlainText, - 2 => ViewDataType::Grid, + 0 => ViewDataType::Block, + 1 => ViewDataType::Grid, _ => { log::error!("Invalid view type: {}", val); - ViewDataType::PlainText + ViewDataType::Block } } } 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 ddf9020243..26173acfaf 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::RichText; + self.data_type = ViewDataType::Block; } // 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::RichText { + if self.data_type != ViewDataType::Block { 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::RichText { + if self.data_type != ViewDataType::Block { 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::RichText; + self.data_type = ViewDataType::Block; 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::RichText; + self.data_type = ViewDataType::Block; } // 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::RichText { + if self.data_type != ViewDataType::Block { 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::RichText { + if self.data_type != ViewDataType::Block { 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::RichText; + self.data_type = ViewDataType::Block; 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::RichText; + self.data_type = ViewDataType::Block; } // 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::RichText { + if self.data_type != ViewDataType::Block { 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::RichText { + if self.data_type != ViewDataType::Block { 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::RichText; + self.data_type = ViewDataType::Block; self.ext_data.clear(); self.view_id.clear(); self.data.clear(); @@ -2821,9 +2821,8 @@ impl ::protobuf::reflect::ProtobufValue for UpdateViewParams { #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum ViewDataType { - RichText = 0, - PlainText = 1, - Grid = 2, + Block = 0, + Grid = 1, } impl ::protobuf::ProtobufEnum for ViewDataType { @@ -2833,17 +2832,15 @@ impl ::protobuf::ProtobufEnum for ViewDataType { fn from_i32(value: i32) -> ::std::option::Option { match value { - 0 => ::std::option::Option::Some(ViewDataType::RichText), - 1 => ::std::option::Option::Some(ViewDataType::PlainText), - 2 => ::std::option::Option::Some(ViewDataType::Grid), + 0 => ::std::option::Option::Some(ViewDataType::Block), + 1 => ::std::option::Option::Some(ViewDataType::Grid), _ => ::std::option::Option::None } } fn values() -> &'static [Self] { static values: &'static [ViewDataType] = &[ - ViewDataType::RichText, - ViewDataType::PlainText, + ViewDataType::Block, ViewDataType::Grid, ]; values @@ -2862,7 +2859,7 @@ impl ::std::marker::Copy for ViewDataType { impl ::std::default::Default for ViewDataType { fn default() -> Self { - ViewDataType::RichText + ViewDataType::Block } } @@ -2907,9 +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*5\n\x0cVi\ - ewDataType\x12\x0c\n\x08RichText\x10\0\x12\r\n\tPlainText\x10\x01\x12\ - \x08\n\x04Grid\x10\x02b\x06proto3\ + \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\ "; 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 af05749a14..2a471bc53f 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,7 +56,6 @@ message UpdateViewParams { oneof one_of_thumbnail { string thumbnail = 4; }; } enum ViewDataType { - RichText = 0; - PlainText = 1; - Grid = 2; + Block = 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 b664557f2b..198953a61f 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::RichText; + let data_type = ViewDataType::Block; View { id: view_id.to_string(),